При написании данной статьи алгоритмы тестировались на 1с ERP релиз 2.4.8.82
В инструкциях указано, что в табличной части документа "Ввод начальных остатков", по каждой строке, создается документ "Первичный документ" с нужным типом (Реализация клиенту, оплата поставщику и т.п.) который отражает ссылку на документ из старой конфигурации.
В инструкции предлагается создавать данный документ по каждой строке табличной части. Это долгий, кропотливый и нудный процесс. При его выполнении пользователями, случается большое количество ошибок, которые затем необходимо выявлять и исправлять. На это уходит огромное количество времени.
Сами остатки, в виде табличной части со ссылкой на первичный документ (указывающий на документ из старой программы), отражают остатки в разрезе документов. Такие остатки загружаются с целью привязки к документам.
В процессе внедрения конфигурации возникает необходимость переноса различного вида остатков. Такой процесс может затянуться на продолжительный срок. После переноса остатков в новую базу, Заказчик может в старой базе закрывать период, изменяя документы и, таким образом, изменяя остатки.
Поэтому процесс переноса остатков может повторится. Чтобы уменьшить количество переносимой заново информации, можно переносить остатки в разрезе документов. Именно поэтому, в 1с ERP необходимо создавать документы "Первичный документ", которые являются ссылкой на документ в старой базе (любого вида).
Предлагаю рассмотреть частный случай, чтобы понять и увидеть на нем предлагаемую технологию автоматического создания и заполнения документов.
Итак, у нас стоит задача переноса остатков Долгов Клиентов в 1с ERP. Не важно из какой базы или учетной системы.
Важно! До переноса остатков, из старой учетной системы в новую учетную систему, 1с ERP, должны быть перенесены и настроены:
- Организации, Клиенты (Партнеры), Контрагенты, Договора (необязательно для данной задачи), валюты.
- Должна быть настроена связь Контрагентов и Партнеров (В Контрагентах указаны Партнеры).
- В Контрагентах должны быть заполнены необходимые реквизиты: Наименование, ИНН, КПП.
Итак, начнем.
Шаг 1. Из старой учетной системы мы выгрузили остатки в виде некой таблицы, например Excel. В этой таблице у нас присутствуют колонки:
- Организация
- Наименование Контрагента
- ИНН (Контрагента)
- КПП (Контрагента)
- валюта
- Сумма долга
- Дата платежа (долга).
Шаг 2. Создаем Вводы начальных остатков по каждой Организации.
По каждой организации ведется отдельный учет долгов. У одного Контрагента могут быть долги перед несколькими организациями!
Для создания Ввода начальных остатков вызываем меню "НСИ и администрирование - Начальное заполнение - начальное заполнение" в открывшемся окне "Начальное заполнение" открываем пункт "Документы ввода начальных остатков". В форме документов открываем в левой панели пункт "Расчеты с партнерами - задолженность клиентов". В правой части окна нажимаем кнопку "Создать".
В окне нового документа выбираем необходимую нам организацию. Сохраняем документ. табличную часть не заполняем.
Шаг 3. Открываем обработку "Загрузку данных из табличного документа".
У меня есть стандартная версия данной обработки с диска ИТС, которая предназначена для запуска в Обычном приложении. В Управляемом приложении эта обработка не запускается. Поэтому, для работы с ней, мне необходимо запустить 1с ERP в режиме обычного приложения.
Не буду рассказывать, как запустить 1с ERP в режиме обычного приложения. Для этого есть инструкции в интернет. Если потребуется, могу привести ссылки.
Шаг 4. Заполняем шапку обработки
В шапке обработки выбираем в поле "Режим загрузки" = "Загрузка в табличную часть".
В поле Ссылка указываем созданный на шаге 2 документ, табличную часть которого мы будем заполнять.
В поле "табличная часть" указываем "Расчеты с партнерами".
В документе "Ввод начальных остатков" множество табличных частей. В данной задаче нам нужна именно указанная табличная часть.
Шаг 5. Заходим на вкладку "Настройка"
При выборе табличной части документа, в Настройках выбрались все реквизиты данной табличной части.
Выключаем не нужные нам колонки "Номер", "Дата". В конфигураторе эти реквизиты называются "НомерРасчетногоДокумента", "ДатаРасчетногоДокумента". Эти колонки заполняются в других типах документа "Ввод начальных остатков" (реквизит документа "Тип операции")
Колонку "Контрагент" перемещаем в самый верх.
Колонка "Тип объекта расчетов" видна только в форме документа. В табличной части ее нет. Она формируется динамически, исходя из заполненных данных в колонках "Объект расчетов", "Расчетный документ". Дело в том, что в нашем Вводе начальных остатков мы будем загружать остатки долгов Клиентов в разрезе Реализаций (в колонке "Тип объекта расчетов" будет "Реализация клиенту").
Шаг 6. На закладке "Табличный документ" добавляем колонки:
ИНН, КПП, Организация, Номер первичного документа, Код партнера, Наименование Контрагента, Дата платежа.
Наименования этих колонок мы записываем в 1 строке в колонки с номерами с 11 по 17.
Колонки ИНН, КПП, Организация служат для поиска данных в базе данных в алгоритме загрузки, который отрабатывает по каждой строке табличной части.
Колонки Номер первичного документа, Код партнера и т.п. - это колонки, в которые динамически подставляются данные алгоритмом. Эти данные необходимы для функционирования алгоритма. По сути это некий буфер обмена данными.
Алгоритм заполняет каждую строку по ячейкам. Заполнение идет слева направо по порядку. колонки буфера обмена заполняются динамически и используются алгоритмом для заполнения остальных колонок.
Шаг 7. Открываем вкладку "Настройка", будем писать код алгоритма!
В строке с колонкой "Контрагент", в колонке "Режим загрузки" указываем "Вычислять".
В колонке "Выражение" вставляем код:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Контрагенты.Ссылка КАК Контрагент,
| Контрагенты.Наименование КАК НаименованиеКонтрагента,
| Контрагенты.Партнер.Код КАК КодПартнера
|ИЗ
| Справочник.Контрагенты КАК Контрагенты
|ГДЕ
| Контрагенты.ИНН = &ИНН
| И Контрагенты.КПП = &КПП
| И Контрагенты.ПометкаУдаления = ЛОЖЬ";
Запрос.установитьПараметр("ИНН", ТекстыЯчеек[11]);
Запрос.установитьПараметр("КПП", ТекстыЯчеек[12]);
Выборка = Запрос.Выполнить().Выбрать();
Если Выборка.Количество()=1 Тогда
Выборка.Следующий();
Результат = Выборка.Контрагент;
//Сообщить("Контрагент = "+Результат);
ТекстыЯчеек[15] = Выборка.КодПартнера;
ТекстыЯчеек[16] = Выборка.НаименованиеКонтрагента;
ИначеЕсли Выборка.Количество()>1 Тогда
Сообщить("По (ИНН,КПП) = ("""+ТекстыЯчеек[11]+","+ТекстыЯчеек[12]+""") найдено более 1 Контрагента!");
Выборка.Следующий();
Результат = Выборка.Контрагент;
//Сообщить("Контрагент = "+Результат);
ТекстыЯчеек[15] = Выборка.КодПартнера;
ТекстыЯчеек[16] = Выборка.НаименованиеКонтрагента;
ИначеЕсли Выборка.Количество()=0 Тогда
Сообщить("Выборка Контрагентов пустая");
КонецЕсли;
Объясняю действие кода:
Алгоритм обработки строки отрабатывает последовательно выражения всех строк сверху вниз по порядку.
Так как строка с колонкой "Контрагент" у нас указана первой сверху в табличной части обработки "загрузка данных из табличного документа", то она будет выполнена первой при начале обработки каждой строки.
В момент начала выполнения Выполняется запрос к базе данных.
В запрос устанавливаются значения, которые берутся как члены массива "ТекстыЯчеек". Из скриншота, в верхней части окна мы видим расшифровку назначения данного массива, в программном контексте выполнения алгоритма заполнения ячейки. В массиве "ТекстыЯчеек" лежат тексты ячеек данной строки. Таким образом, обратившись к члену массива с соответствующим номером, мы получим текст соседней ячейки. Таким образом, мы получаем Тексты колонок "ИНН" и "КПП", а точнее ячеек строки в текущей строке, которая сейчас обрабатывается алгоритмом.
Поясню. Алгоритм обработки выполняется в каждой строке табличной части последовательно. Закладка "Табличный документ". Например, алгоритм начал выполняться в строке 2. Далее, в каждой строке начинается последовательно запускаться алгоритмы по каждой колонке. Берутся колонки, которые указаны в Настройках. Выполняются алгоритмы по их заполнению последовательно, сверху вниз. Например, сначала выполняется алгоритм колонки Контрагент, затем Партнер, затем Договор и т.д.
Далее заполняется переменная Выборка результатом запроса.
Далее Выборка последовательно проходится в цикле.
В отдельных случаях выволятся сообщения об ошибках (когда в запросе по ИНН и КПП найдено несколько Контрагентов или ни одного).
Если все ок и Контрагент найден (по ИНН и КПП) тогда выполняется основной алгоритм обработки Выборки.
Если найдено несколько Контрагентов (по ИНН и КПП), берется первый. В сообщения выводится предупреждение об этом. Пользователь сам должен подумать что в данной ситуации делать (возможно потребуется заменить Контрагента в сформированном документе).
ВАЖНО! В тексты ячеек 15 и 16 записываются КодПартнера и НаименованиеКонтрагента. Текст этих ячеек будут использоваться в алгоритмах заполнения в последующих колонках.
Почему код партнера - это понятно. Чтобы найти ссылки по коду. Почему именно наименование а не код Контрагента? Такой вопрос задаст программист или пользователь, который незнаком с ERP.
Отвечаю - потому что в 1с ERP, в справочнике Контрагенты, нет стандартного реквизита "код". У справочника, на закладке Данные, тип кода = Строка, длина кода = 0. Основное представление = наименование. Такая же ситуация у половины справочников в 1с ERP.
В строке с колонкой "Партнер", в колонке "Режим загрузки" указываем "Вычислять".
В колонке "Выражение" вставляем код:
Результат = Справочники.Партнеры.НайтиПоКоду(ТекстыЯчеек[15]);
Объясняю действие кода:
Используется текст ячейки, который был заполнен на предыдущем шаге (при выполнении запроса к БД).
Ищется ссылка по коду и подставляется в значение ячейки.
В строках с колонками "Договор" и "Валюта", "Сумма", в колонке "Режим загрузки" указываем "Искать".
В колонке "Выражение" вставляем "Наименование", "Код", "" соответственно.
В строке с колонкой "Дата платежа", в колонке "Режим загрузки" указываем "Вычислять".
В колонке "Выражение" вставляем код:
Результат = Дата(ТекстыЯчеек[17]);
Объясняю действие кода:
Берется текст ячейки 17. В нее будет заносится текстовые данные, отражающие "Дату платежа".
Формат данных "ГГГММДД" например "20190101". ГГГГ = 2019 (год). ММ = число месяца, ДД - число дня
В строках с колонками "Сумма (регл.)", "Сумма (упр.)", в колонке "Режим загрузки" указываем "Вычислять".
В колонке "Выражение" вставляем код:
Результат = ТекстыЯчеек[5];
Объясняю действие кода:
Берется текст ячейки 5. В ней указывается сумма долга.
В строке с колонкой "Объект расчетов", в колонке "Режим загрузки" указываем "Вычислять".
В колонке "Выражение" вставляем код:
ПервичныйДокумент = Документы.ПервичныйДокумент.СоздатьДокумент();
ПервичныйДокумент.Дата = ТекущаяДата();
ПервичныйДокумент.ТипПервичногоДокумента = Перечисления.ТипыПервичныхДокументов.РеализацияКлиенту;
ПервичныйДокумент.Организация = Справочники.Организации.НайтиПоНаименованию(ТекстыЯчеек[13]);
ПервичныйДокумент.Контрагент = Справочники.Контрагенты.НайтиПоНаименованию(ТекстыЯчеек[16]);
ПервичныйДокумент.Партнер = Справочники.Партнеры.НайтиПоКоду(ТекстыЯчеек[15]);
ПервичныйДокумент.Валюта = Справочники.Валюты.НайтипоКоду("643");
ПервичныйДокумент.ПорядокРасчетов = Перечисления.ПорядокРасчетов.ПоНакладным;
ПервичныйДокумент.СуммаДокумента = ТекстыЯчеек[5];
ПервичныйДокумент.СуммаРегл = ТекстыЯчеек[5];
ПервичныйДокумент.Договор = Справочники.ДоговорыКонтрагентов.ПустаяСсылка();
Попытка
ПервичныйДокумент.Записать(РежимЗаписиДокумента.Проведение);
Сообщить("документ создался");
Результат = ПервичныйДОкумент.Ссылка;
ТекстыЯчеек[14] = ПервичныйДОкумент.Номер;
ИСключение
ПервичныйДокумент = Документы.ПервичныйДокумент.СоздатьДокумент();
Сообщить("документ НЕ создался по причине: "+ОписаниеОшибки());
КонецПопытки;
Объясняю действие кода:
Создается новый экземпляр документа ПервичныйДокумент с заполнением реквизитов.
При заполнении реквизитов используются ранее заполненные вручную или динамически колонки (массив ТекстыЯчеек).
После заполнения, документ записывается в базу данных, с проведением.
Если попытка записи удалась, то в значение текущей ячейки записывается ссылка на созданный документ.
В текст ячейки 14 записывается номер созданного документа (для доступа в алгоритме заполнения следующей ячейки).
В строке с колонкой "Расчетный документ", в колонке "Режим загрузки" указываем "Вычислять".
В колонке "Выражение" вставляем код:
ПервичныйДокумент_Номер = ТекстыЯчеек[14];
Если ПервичныйДокумент_Номер<>"" Тогда
Результат = Документы.ПервичныйДокумент.НайтиПоНомеру(ПервичныйДОкумент_Номер , ТекущаяДата());
КонецЕсли;
Объясняю действие кода:
Используется текст ячейки 14. Если на предыдущем шаге успешно создан документ в БД, то в ячейку 14 записан его номер. Этот номер используется для нахождения ссылки на данный документ. Эта ссылка записывается в значение ячейки.
Шаг 8. Заполняем табличную часть на закладке "Табличный документ".
Данные заполняются, как указано на скриншоте.
Важно заполнить ИНН, КПП Контрагента, Наименование Организации, Дату платежа, Валюту, Сумму.
Шаг 9. Нажимаем кнопку "Загрузить".
Обработка отработает алгоритмы и перенесет данные в табличную часть документа.
По каждой строке создастся документ "Первичный документ", его ссылка будет прописана в строке табличной части документа "Ввод начальных остатков".
Если будут ошибки, то их необходимо обработать вручную, с применением мозга. Это отдельная задача, не рассматриваемая в данной статье.
Шаг 10. Проверяем заполнение табличной части документа "Ввод начальных остатков".
Если что-то не сработало несколько раз, можно дополнить или изменить код алгоритмов.
Дополнительно я выложил настройки стандартной обработки "загрузка данных из табличного документа". Настройки включают в себя программный код, который приведен в статье.
Кроме того, выложил mxl файл табличного документа. В нем приведен пример заполнения табличной части обработки данными.
Я использовал описанный в статье алгоритм для заполнения большого количества документов Ввод начальных остатков при внедрении 1с ERP на предприятии.
Удачи вам в делах!