Имя: Пароль:
1C
1С v8
проверка на клонов
0 DEaD_EGOR
 
01.04.16
14:10
Народ, всем привет. Пишу обработку, которая заполняет контрагентов из экселя... как правильно прописать функционал проверки на одинаковые значения? ну, например, если обработка сработала больше одного раза, чтоб клонов не создавала.. Пишу под УТ 10,3..
Процедура СозданиеКонтрагента (мФорма)
    
    Для Каждого СтрокаТаблицы из Таблица  Цикл
        НовыйОбъект = Справочники.Контрагенты.СоздатьЭлемент();
        НовыйОбъект.ГоловнойКонтрагент = СтрокаТаблицы.НазваниеФирмы;
        НовыйОбъект.Наименование = СтрокаТаблицы.Имя;
        НовыйОбъект.НаименованиеПолное = СтрокаТаблицы.Имя;
        НовыйОбъект.ЮрФизЛицо = Перечисления.ЮрФизЛицо.ЮрЛицо;
        НовыйОбъект.КПП = СтрокаТаблицы.КППОбъекта;
        Попытка
            НовыйОбъект.Записать();
        Исключение
            Продолжить;
        КонецПопытки;
        
        //проверка на контрагента
        
        КонтагентСсылка = НовыйОбъект.Ссылка;
        МоеЗаполнение = Новый Структура("Представление,Тип,Вид",СтрокаТаблицы.ПИндекс + " " + СтрокаТаблицы.Регион + " " + СтрокаТаблицы.Город + " " + СтрокаТаблицы.Улица + " " + СтрокаТаблицы.НомерДома,Перечисления.ТипыКонтактнойИнформации.Адрес,Справочники.ВидыКонтактнойИнформации.ФактАдресОрганизации);
        
        НЗ_КИ = РегистрыСведений.КонтактнаяИнформация.СоздатьНаборЗаписей();
        НЗ_КИ.Отбор.Объект.Значение      = КонтагентСсылка;
        НЗ_КИ.Отбор.Объект.Использование = Истина;
        НЗ_КИ.Отбор.Тип.Значение         = Перечисления.ТипыКонтактнойИнформации.Адрес;
        НЗ_КИ.Отбор.Тип.Использование    = Истина;
        НЗ_КИ.Отбор.Вид.Значение         = Справочники.ВидыКонтактнойИнформации.ФактАдресОрганизации;
        НЗ_КИ.Отбор.Вид.Использование    = Истина;
        НЗ_КИ.Прочитать();
        //НаборЗаписей = НЗ_КИ.Выгрузить();
        НоваяЗаписьНабора = НЗ_КИ.Добавить();
        НоваяЗаписьНабора.Объект = КонтагентСсылка;
        НоваяЗаписьНабора.Тип = Перечисления.ТипыКонтактнойИнформации.Адрес;
        НоваяЗаписьНабора.Вид = Справочники.ВидыКонтактнойИнформации.ФактАдресОрганизации;
        НоваяЗаписьНабора.Представление = МоеЗаполнение.Представление;
        //НЗ_КИ.Загрузить(НаборЗаписей);
        НЗ_КИ.Записать(Истина);// если 'ИСТИНА' - будет замещение данных
        
        
        
    КонецЦикла;
    
КонецПроцедуры

вод собсна кусок кода...
1 Fish
 
01.04.16
14:12
(0) Проверяй по ИНН/КПП.
2 Лодырь
 
01.04.16
14:14
(1) он ИНН вообще не пишет )
3 Fish
 
01.04.16
14:15
(2) Тогда ой :)
4 DEaD_EGOR
 
01.04.16
14:15
(1) ну инн у меня в данных нет, только кпп. и как это реализовать? я-нуб в 1с, это моя вторая обработка...Я так понял. это нужно функцию прописать и вызывать её из процедуры?
5 DEaD_EGOR
 
01.04.16
14:17
(4) причём нужно вызывать из момента чтения и создания табзнач
Процедура ПрочитатьНажатие(Элемент)
    
    //подключаемся к эксел
    Попытка
        Excel = Новый COMОбъект("Excel.Application");
        Excel.WorkBooks.Open(ИмяФайла);
        Состояние("Обработка файла Microsoft Excel...");
    Исключение
        Сообщить("Ошибка при открытии файла с помощью Excel! Загрузка не будет произведена!");
        Сообщить(ОписаниеОшибки());
        Возврат;
    КонецПопытки;
    
    Попытка
        //Открываем необходимый лист
        Excel.Sheets(1).Select();  // лист 1, по умолчанию  
    Исключение
        //Закрываем Excel
        Excel.ActiveWorkbook.Close();     
        Excel = 0;
        Сообщить("Файл "+Строка(ИмяФайла)+" не соответствует необходимому формату! Первый лист не найден!");
        ОтменитьТранзакцию();
        Возврат;
    КонецПопытки;    
    
    //Получим количество строк и колонок.
    //В разных версиях Excel получаются по-разному, поэтому сначала определим версию Excel
    Версия = Лев(Excel.Version,Найти(Excel.Version,".")-1);
    Если Версия = "8" тогда
        ФайлСтрок   = Excel.Cells.CurrentRegion.Rows.Count;
        ФайлКолонок = Макс(Excel.Cells.CurrentRegion.Columns.Count, 27);
    Иначе
        ФайлСтрок   = Excel.Cells(1,1).SpecialCells(11).Row;
        ФайлКолонок = Excel.Cells(1,1).SpecialCells(11).Column;  
    Конецесли;
    
    //создание колонок табличного документа  
    ТабЗнач = Новый ТаблицаЗначений;
    ТабЗнач.Колонки.Добавить("Завод");
    ТабЗнач.Колонки.Добавить("Имя");
    ТабЗнач.Колонки.Добавить("НазваниеФирмы");
    ТабЗнач.Колонки.Добавить("КППОбъекта");
    ТабЗнач.Колонки.Добавить("КодРегиона");
    ТабЗнач.Колонки.Добавить("Регион");     
    ТабЗнач.Колонки.Добавить("ПИндекс");
    ТабЗнач.Колонки.Добавить("Город");
    ТабЗнач.Колонки.Добавить("Улица");
    ТабЗнач.Колонки.Добавить("НомерДома");
    ТабЗнач.Колонки.Добавить("Дополнение");
    ТабЗнач.Колонки.Добавить("Телефон");
    
    //считываем первую строку и генерируем колонки
    Для НС = 2 По ФайлСтрок Цикл
        НоваяСтрока = ТабЗнач.Добавить();
        НоваяСтрока.Завод = Excel.Cells(НС, 1).Value;
        НоваяСтрока.Имя = (Excel.Cells(НС, 2).Value); //Это грузополучатели-торговые точки    
        НоваяСтрока.НазваниеФирмы = (Excel.Cells(НС, 4).Value); //это контрагенты - плательщики
        НоваяСтрока.КППОбъекта = Excel.Cells(НС, 9).Value;
        НоваяСтрока.КодРегиона = Excel.Cells(НС, 12).Value;
        НоваяСтрока.Регион = Excel.Cells(НС, 13).Value;
        НоваяСтрока.ПИндекс = Excel.Cells(НС, 14).Value;
        НоваяСтрока.Город = Excel.Cells(НС, 15).Value;
        НоваяСтрока.Улица = Excel.Cells(НС, 16).Value;
        НоваяСтрока.НомерДома = Excel.Cells(НС, 17).Value;
        НоваяСтрока.Дополнение = Excel.Cells(НС, 18).Value; //проверять на наличие
        НоваяСтрока.Телефон = Excel.Cells(НС, 19).Value;
    КонецЦикла;
    
    // Закрыть COM соединение для экономии памяти
    Excel.Application.Quit();
    
    //поместить считанные данные в форму обработки
    ЭлементыФормы.Таблица.Значение = ТабЗнач;
    ЭлементыФормы.Таблица.СоздатьКолонки();
    
    мФорма = ПолучитьФорму (Справочники.Контрагенты.ПолучитьФормуНовогоЭлемента());
    СозданиеКонтрагента(мФорма);
    
    мСообщение = Новый СообщениеПользователю();
    мСообщение.Текст = "Контрагенты загружены";
    мСообщение.Сообщить();
КонецПроцедуры
6 Fish
 
01.04.16
14:17
(4) Тебе нужно перед тем, как создавать нового контрагента, осуществить поиск уже существующего по какому-либо уникальному признаку. Для юриков это обычно сочетание ИНН/КПП.
7 aleks_default
 
01.04.16
14:18
Проверяй на клоны еще в таблице, до создания элемента справочника. Остальное от лукавого
8 Рэйв
 
01.04.16
14:18
(5)Ищи перед созданием запросом по
ГоловнойКонтрагент И Наименование И НаименованиеПолное и КПП
9 Мэс33
 
01.04.16
14:19
(0)
- прочитай эксель
- прочитай справочник контрагентов
- найди клонов, которые не клоны - запиши в 1С
- по клонам: ругнись, оповести пользователя
10 DEaD_EGOR
 
01.04.16
14:19
(7) Я просто пока тестирую обработку, когда жмакаю кнопку Прочитать, у меня каждый раз одни и те же забиваются контрагенты... Это только запросом лечится, больше никак?
11 Рэйв
 
01.04.16
14:21
(10)А запросом твоя религия запрещает?
12 DEaD_EGOR
 
01.04.16
14:21
(9) умом понимаю, но как это сделать "найди клонов, которые не клоны - запиши в 1С "?
13 DEaD_EGOR
 
01.04.16
14:21
(11) нет, просто с ними я ещё ни разу не работал....
14 Рэйв
 
01.04.16
14:22
(13)Ну вот.Отличный повод научиться.Ибо все равно придется.
15 Fish
 
01.04.16
14:22
(12) Читай (6) и (7) внимательно.
16 Московский
 
01.04.16
14:23
(0) Запросом жеж!
17 DEaD_EGOR
 
01.04.16
14:23
(14) я боюсь мне сроки не позволят разобрать эту тему))) мне обработку по идее надо к понедельнику сделать, а я только реализовал чтение и запись контрагентов без адресов и всего остального.. я понимаю, что подобную обработку проф напишет за пол дня-день.. а я уже 3й день над ней кипю..
18 Рэйв
 
01.04.16
14:24
(17)А ты нафига такие сроки ставил если еще нуб в 1С?  Надо с запасом тогда брать раза в три больше
19 DEaD_EGOR
 
01.04.16
14:25
(18) такие это какие?
20 Рэйв
 
01.04.16
14:26
(19)"до понедельника".
Надо было недели две взять.
21 DEaD_EGOR
 
01.04.16
14:27
(20) это не от меня зависит. начальство сказало, а я делаю.. вернее пытаюсь сделать))
22 Рэйв
 
01.04.16
14:28
(21)"Начальство сказало, а ты не согласился" у вас не вариант чтоли? :-)  Не привыкай к плохому. С начальством можно и нужно спорить.
23 Рэйв
 
01.04.16
14:29
Если значешь что не успеешь -  надо было требовать увеличить сроки
24 DEaD_EGOR
 
01.04.16
14:32
(21) (22)Это всё понятно. Только долго объяснять, да и к теме не относится...
25 DEaD_EGOR
 
01.04.16
14:43
Я начал так..
мИмяагента = Справочники.Контрагенты.НайтиПоРеквизиту(КПП);
    Если мИмяагента = ...
а дальше не могу разобраться, как правильно написать... если имя агента равняется уже имеющемуся, тогда возврат. как написать выражение про имеющийся реквизит?
26 Fish
 
01.04.16
14:47
(25) посмотри в СП, что возвращает .НайтиПоРеквизиту()
27 aleks_default
 
01.04.16
14:50
(25) Че совсем все плохо? С голодухи в 1с подался?
28 DEaD_EGOR
 
01.04.16
14:52
(26) возвращает найденную ссылку... либо пустую ссылку. если значение не найдено

(27) Ну не совсем с голодухи... Но тоже от жизненной ситуации
29 Fish
 
01.04.16
14:56
(28) Ну вот. Сначала тебе надо проверить на ЗначениеЗаполнено() или на пустую ссылку, и если ссылка не пустая уже сравнивать реквизиты. А если пустая - создаёшь нового контрагента.
30 aleks_default
 
01.04.16
14:58
(28) Лучше поищи готовую загрузку на ИС. Проще взять там уже готовую и поправить, чем все заново писать.
31 Мэс33
 
01.04.16
15:01
(27) так вот откуда 1Сники берутся. С голодухи.
32 Мэс33
 
01.04.16
15:07
(0) Простой банальный вариант:
Пишешь функцию, которая читает файл, создает ТЗ, закрывает файл и возвращает ТЗ.
Например:
Функция ПрочитатьЁксельМопсель()
  ...
  ...
  Возврат ТЗ;
КонецФункции

Потом пишешь функцию, которая ищет контрагента:
Функция НайтиКонтрагента(КПП, Наименование, )
  Контр = Справочники.Контрагенты.ПустаяСсылка;
  ... тут ищешь
  ... ищешь
  ...
  Возврат Контр; // либо ПустаяСсылка будет либо контрагент
КонецФункции

И третье:
Процедура СоздатьКонтрагента(КПП, Наименование, что-то еще)
КонецПроцедуры

А потом в основной функции:
- дергаешь чтение файла
- перебираешь строки, и по каждой строке дергаешь вторую функцию
- если в ответе пустая ссылка - дергаешь создание контрагента


Это понятный абсолютно всем код. Не оптимальный. Но надо с чего-то начать.
33 DEaD_EGOR
 
01.04.16
15:07
(30) ну это и стандартную из ИТС можно взять, только она мне не поможет особливо. у меня есть документ и доработанная УТ 10,3. в доке указаны контрагенты с контактной инфой, и их надо загрузить единоразово в справочник но по городам раскидать автоматом
34 DEaD_EGOR
 
01.04.16
15:09
(32) ну где то по этому принципу я и делаю...
35 Мэс33
 
01.04.16
15:10
(34) в чем конкретно загвоздка?
36 DEaD_EGOR
 
01.04.16
15:13
(35) в данном моменте их 2. первая-из вашего поста (32) "Тут ищешь" в смысле - искать по имеющемуся справочнику на наличие чего? пустой ссылки или имеющегося значения?


вторая-не заполняется адрес в контактных данных по классификатору..
37 DEaD_EGOR
 
01.04.16
15:19
Контр = Справочники.Контрагенты.НайтиПоРеквизиту(КПП);
    Если Контр <> Справочники.Контрагенты.ПустаяСсылка()  Тогда
        Возврат Контр;
        Иначе ?
что прописать в иначе? создание нового контрагента?
38 Fish
 
01.04.16
15:20
(37) Да.
39 Мэс33
 
01.04.16
15:22
(36) уникальных идентификаторов типа ИНН у тебя нет.
Тогда ищи по наименованию и по КПП.
Причем, когда будешь читать с екселя, используй для имени СокрЛП(), и пиши полученное значение в 1С.

(37)
Тебе же надо найти по совпадению либо КПП, либо наименованию, либо по КПП+Наименование? КПП - уникальное?
40 Мэс33
 
01.04.16
15:23
(37) вру, у нас в стране нет понятия КПП ))). Есть БИН.

Ок, тогда в (37) - отдельная функция не нужна:

Контр = Справочники.Контрагенты.НайтиПоРеквизиту(КПП);
Если Контр = Справочники.Контрагенты.ПустаяСсылка()  Тогда
     // создаем контрагента;
КонецЕсли;
41 Мэс33
 
01.04.16
15:23
(40) Контр = Справочники.Контрагенты.НайтиПоРеквизиту("КПП", КПП);
42 DEaD_EGOR
 
01.04.16
15:24
(40) Фак, не уникален КПП((( опытным путём выяснил, что кпп повторяется. остаётся только наименование...
43 Мэс33
 
01.04.16
15:26
(42) Ну тогда по наименованию.
И тому, кто попросил загрузить, так и скажешь  - ищу по имени. Сорри, если будут ошибки.
44 Pentosh
 
01.04.16
15:26
(42) не уникальный может потому что уже дубли есть?
45 Fish
 
01.04.16
15:27
(42) Наименования могут быть такие: ООО "Ромашка", Ромашка ООО, Ромашка   ООО, и т.д.. И это всё будет один контрагент :)
46 Мэс33
 
01.04.16
15:27
(45) ну уж сорри.
47 Мэс33
 
01.04.16
15:28
(42) в экселе сводными таблицами проверь - есть ли дубли.
и в 1С запросом проверь.
48 DEaD_EGOR
 
01.04.16
15:33
(45) не, у меня имя контрагента одного принципа "5612-Пятерочка"... Думаю-даже раскладывать строку и искать совпадения по коду в начале имени смысла нет..
49 Fish
 
01.04.16
15:35
(48) А "5612" - это уникальный код? Тогда имело бы смысл к нему привязаться.
50 aleks_default
 
01.04.16
15:35
(47)см. (17)
51 Мэс33
 
01.04.16
15:49
(50) посмотрел, спасибо.
52 Мэс33
 
01.04.16
15:49
(49) легко проверить.
В экселе выдернуть первые несколько символов и поискать дубли.
53 Chameleon1980
 
01.04.16
16:01
Функцию, которая запросом по набору реквизитов ищет уже существующего контра:

типа (например у нас есть состав Наименование и КПП)

Функция НайтиСоздатьКонтрагента(Наименование, КПП="")
    
    Запрос=Новый Запрос;
    
    ТекстЗапроса="ВЫБРАТЬ РАЗРЕШЕННЫЕ ПЕРВЫЕ 1
                 |    Контрагенты.Ссылка
                 |ИЗ
                 |    Справочник.Контрагенты КАК Контрагенты
                 |ГДЕ
                 |    Контрагенты.Наименование = &ВыбНаименование
                 |    И ВЫБОР
                 |            КОГДА &ЕстьУсловиеПоКПП
                 |                ТОГДА Контрагенты.КПП = &ВыбКПП
                 |            ИНАЧЕ ИСТИНА
                 |        КОНЕЦ";
    
                
    Запрос.Текст=ТекстЗапроса;
    
    Запрос.УстановитьПараметр("ВыбНаименование", Наименование);
    Запрос.УстановитьПараметр("ВыбКПП", КПП);
    
    Если ПустаяСтрока(КПП) Тогда
        Запрос.УстановитьПараметр("ЕстьУсловиеПоКПП", Ложь);
    Иначе
        Запрос.УстановитьПараметр("ЕстьУсловиеПоКПП", Истина);
    КонецЕсли;
    
    Результат=Запрос.Выполнить();
    
    Если Результат.Пустой() Тогда
        // запросом не нашли. вызываем функцию создания нового
        Контрагент=СоздатьКонтрагента(Наименование, КПП);
    Иначе
        Выборка=Результат.Выбрать();
        Если Выборка.Следующий() Тогда
            Контрагент=Выборка.Ссылка;
        Иначе
            Контрагент=СоздатьКонтрагента(Наименование, КПП);
        КонецЕсли;
    КонецЕсли;
    
    Возврат Контрагент;
    
КонецФункции