1С 7.7 сегодня живет в странном статусе: платформа давно не новая, типовые решения на ней уступили место 1С 8, но в реальном бизнесе старые базы продолжают работать. Часто это сильно доработанные конфигурации, которые годами закрывали конкретные процессы компании, и переписать их «на восьмерку» быстро не получается. С нейросетями похожая история: для 1С 8 примеров, обсуждений и готовых фрагментов заметно больше, а код под 7.7 они пишут менее уверенно. Синтаксис вроде знакомый, но объектная модель, запросы, периодические реквизиты и старые приемы работы отличаются. Поэтому использовать нейросеть для 7.7 можно, но не как автопилот, а как помощника, которому обязательно нужны реальные файлы, описание метаданных и проверка человеком.
Есть старые задачи, которые не выглядят эффектно, но хорошо показывают, где нейросеть может быть полезна в разработке. Не «написать сервис с нуля», а разобрать уже существующий код, понять чужую конфигурацию, не сломать старую логику и аккуратно добавить несколько новых сценариев.
У меня была как раз такая задача: внешняя обработка для 1С 7.7 загружала XML-файлы универсального передаточного документа в документ «Приходная накладная». Нужно было доработать ее под реальные файлы поставщиков.
На руках были два XML-файла с реальной выгрузкой, из которых потом и должна была идти загрузка. Формат у таких файлов стандартный, но стандартный не значит простой: много вложенных узлов, атрибуты на разных уровнях, отдельные блоки для продавца, товаров, маркировки, налогов, таможенных деклараций и страны происхождения. Разбирать это вручную можно, но времени ушло бы заметно больше. Я просто передал оба XML-файла нейросети вместе с текущим модулем, и она с первого раза правильно нашла, откуда брать основные реквизиты: наименование товара, количество, цену, артикул, контрольные идентификационные знаки, номер декларации, код и название страны.
Сразу оговорюсь: нейросеть не «сделала все сама». Я использовал GPT-5.5, давал ей контекст, примеры XML, описание реквизитов и текущий модуль на встроенном языке 1С, а дальше мы шаг за шагом доводили обработку до нужного поведения.
Еще один бытовой момент: прямой связи между средой, где я работал с нейросетью, и модулями 1С у меня не было. Я разрабатывал в Codex, но сам модуль внешней обработки в 1С жил отдельно. Поэтому приходилось заниматься обычным копипастом: фрагменты из модуля переносить в диалог с нейросетью, затем готовые куски кода возвращать обратно в 1С и проверять уже там. Это не очень удобно, зато быстро работает, если держать под рукой исходный модуль, XML-примеры и описание реквизитов.
Что уже было
На старте обработка уже умела загружать базовый универсальный передаточный документ:
-
поставщик искался по идентификационному номеру налогоплательщика;
-
если поставщик не найден, создавался новый контрагент;
-
товар искался по полному наименованию;
-
если товар не найден, создавалась новая номенклатура;
-
контрольный идентификационный знак маркировки из XML-файла попадал в реквизит строки «Кюар»;
-
если у товара было 10 контрольных идентификационных знаков, создавалось 10 строк по 1 штуке;
-
если маркировки не было, создавалась одна строка с общим количеством.
Для простого документа этого хватало. Но на реальных XML-файлах почти сразу всплыли детали, которые в первой версии не учитывались: разные единицы измерения, артикулы, грузовые таможенные декларации, страна происхождения и ситуации, когда один товар надо разбивать на несколько строк.
Как выглядел первый запрос к нейросети
Я не стал просить «доработай загрузку универсального передаточного документа». Такой запрос слишком общий. Вместо этого дал файлы и короткое техническое задание:
Доработать только код. Есть файл описания реквизитов, XML с загружаемыми данными и модуль на встроенном языке 1С с уже сделанным кодом.
Уже сделано: загрузка из XML в приходную накладную. Товар ищем по
СокрЛП(ПолнНаименование), если не находим — создаем новый в корне справочника «Номенклатура». Поставщик ищется по идентификационному номеру налогоплательщика, если нет — создается новый. В XML<КИЗ>попадает в приходной в «Кюар».Доработать: единица измерения бывает не только с кодом 796. Если в товаре XML есть
АртикулТов, добавить в номенклатуру «Артикул». В приходе бывает грузовая таможенная декларация:НомерДТ, код страны и название страны. Декларация идет на определенное количество товара. Один товар может быть 10 штук с одной декларацией или 10 штук с одной декларацией и 5 штук с другой — тогда в приходе должны быть две строки.
Такой формат сработал лучше, чем абстрактное описание. Особенно для 1С 7.7, где нельзя полагаться на типовые названия реквизитов: в одной базе это ПолнНаименование, в другой — что-то еще, а табличная часть может быть доработана годами эксплуатации.
Отдельно я всегда пишу «доработать только код». Причина простая. В 1С в XML-форматах могут храниться не только данные обмена, но и внутренние вещи: формы, описания метаданных, части конфигурации. Такие форматы специфичные, не всегда публично описаны и плохо подходят для генерации «на глаз». Если не ограничить задачу, нейросеть может начать править XML-теги или предлагать изменения XML-частей кодовой базы 1С. Для 1С 7.7 это особенно опасно: ошибка в таком фрагменте может привести не к синтаксической ошибке в модуле, а к повреждению структуры, которую потом сложно восстановить. Поэтому правило простое: XML можно читать как источник данных и как справочник по структуре, но менять нужно только модуль с кодом.
При этом первый вариант от нейросети не был идеальным. Она пыталась решать часть задач слишком прямолинейно: где-то предлагала хардкодинг, где-то конструкции в стиле «найти по коду» или «найти по наименованию» без нормального использования запросов, хотя в существующем модуле поиск по справочникам уже был сделан через объект Запрос. Я отдельно указал на это и попросил переписать в том же стиле, через запросы 1С 7.7. Через пару минут GPT-5.5 перестроила код: появились отдельные функции поиска по коду, по наименованию и создания элемента справочника, уже без лишнего хардкода и ближе к тому, как был написан исходный модуль.
Единица измерения: не всегда 796
В старом коде единица измерения для новой номенклатуры была фактически захардкожена:
ЕдиницаИзм = НайтиЕдиницуИзмеренияПоКоду("796");
Код 796 — это «штука». Но в XML-файле может прийти, например, коробка:
<СведТов НаимЕдИзм="кор" ОКЕИ_Тов="..." КолТов="10" ...>
Если молча загрузить это как штуки, учет будет неправильным: 10 коробок превратятся в 10 штук. Поэтому я попросил учесть единицу из XML-файла.
Поэтому из строки товара стали читать и код, и наименование:
КодЕдиницы = АтрибутXML(УзелТовара, "ОКЕИ_Тов");НаименованиеЕдиницы = АтрибутXML(УзелТовара, "НаимЕдИзм");Товар = ПолучитьИлиСоздатьНоменклатуру(Наименование,КодЕдиницы,НаименованиеЕдиницы,Артикул);
Дальше логика такая:
-
Ищем единицу по
КодЕдин. -
Если не нашли — ищем по наименованию.
-
Если не нашли и в XML-файле есть данные — создаем новую единицу.
Фрагмент функции:
ЕдиницаИзм = НайтиЕдиницуИзмеренияПоКоду(КодЕдиницы);Если ПустоеЗначение(ЕдиницаИзм) = 0 ТогдаВозврат ЕдиницаИзм;КонецЕсли;ЕдиницаИзм = НайтиЕдиницуИзмеренияПоНаименованию(НаименованиеЕдиницы);Если ПустоеЗначение(ЕдиницаИзм) = 0 ТогдаВозврат ЕдиницаИзм;КонецЕсли;Спр = СоздатьОбъект("Справочник.КодыЕдиниц");Спр.Новый();Если НаименованиеЕдиницы <> "" ТогдаСпр.Наименование = НаименованиеЕдиницы;ИначеСпр.Наименование = КодЕдиницы;КонецЕсли;Спр.КодЕдин = КодЕдиницы;Спр.Записать();
После этого найденная или созданная единица записывается в периодический реквизит номенклатуры ЕдиницаИзм.
Отдельный вопрос про «кор»
После первой правки я отдельно спросил:
«кор» — в файле есть такая единица, а у нас её нет в справочнике. Какие есть предложения?
Вариантов было несколько:
-
подменять неизвестную единицу на «шт»;
-
создать единицу автоматически;
-
завести таблицу соответствий и коэффициенты пересчета.
Подменять на «шт» я отбросил сразу. Это удобно только до первой инвентаризации. Таблица соответствий с коэффициентами — самый правильный вариант для сложного обмена, но в текущих XML-файлах не было информации вроде «1 кор = 12 шт». Значит, автоматически пересчитать коробки в штуки корректно нельзя.
Остановились на простом и честном варианте: если в XML-файле пришла единица и ее нет в справочнике, обработка создает ее и сообщает об этом пользователю.
Артикул из XML-файла
Артикул в одном из файлов приходил в ДопСведТов:
<ДопСведТов АртикулТов="ASX5010-5" КодТов="ASX5010-5" ПрТовРаб="1">
В код добавили чтение атрибута:
УзелДопСведТов = УзелТовара.ВыбратьУзел("ДопСведТов");Артикул = АтрибутXML(УзелДопСведТов, "АртикулТов");
При создании новой номенклатуры все просто:
Спр.Артикул = Артикул;
Но для уже найденного товара нужна аккуратность. Если в XML-файле артикул пустой, нельзя затирать значение в базе. Поэтому обновление сделали только при непустом артикуле:
Если Артикул <> "" ТогдаЕсли СпрНом.Артикул <> Артикул ТогдаСпрНом.Артикул = Артикул;СпрНом.Записать();КонецЕсли;КонецЕсли;
Мелочь, но именно на таких мелочах часто ломаются загрузки: один поставщик прислал артикул, другой не прислал, и в базе внезапно пусто.
Грузовая таможенная декларация и страна происхождения
Дальше дошли до грузовой таможенной декларации. В XML-файле она лежит в СвДТ:
<СвДТ КодПроисх="156" НомерДТ="10702070/270426/5157184"/>
А название страны — в другом узле:
<ДопСведТов ПрТовРаб="1"><КрНаимСтрПр>КИТАЙ</КрНаимСтрПр></ДопСведТов>
По описанию конфигурации нашли справочник ГТД. У него есть реквизиты Страна, цифровойкод и КодСтран. Для кода страны используется справочник СтраныКод.
Функция получения или создания грузовой таможенной декларации получилась такой:
Функция ПолучитьИлиСоздатьГТД(НомерГТД, КодСтраны, НаименованиеСтраны)НомерГТД = ОбрезатьСтроку(НомерГТД, 50);Если НомерГТД = "" ТогдаВозврат "";КонецЕсли;ГТД = НайтиГТДПоНомеру(НомерГТД);Если ПустоеЗначение(ГТД) = 0 ТогдаВозврат ГТД;КонецЕсли;Страна = ПолучитьИлиСоздатьСтрану(КодСтраны, НаименованиеСтраны);Спр = СоздатьОбъект("Справочник.ГТД");Спр.Новый();Спр.Наименование = НомерГТД;Спр.Страна = ОбрезатьСтроку(НаименованиеСтраны, 100);Спр.цифровойкод = ОбрезатьСтроку(КодСтраны, 10);Если ПустоеЗначение(Страна) = 0 ТогдаСпр.КодСтран = Страна;КонецЕсли;Спр.Записать();Возврат Спр.ТекущийЭлемент();КонецФункции
Что такое «ОбрезатьСтроку "? Дело в том, что строка полученная из файла, может быть разного размера. А когда ищем по наименованию, или запросом, то для 1С 7.7 надежнее привести её длину к реально используемой в текущей базе данных.
А процедура добавления строки прихода получила еще один параметр:
Процедура ДобавитьСтрокуПрихода(Док, Товар, Количество, Цена, Сумма, НДС, Кюар, ГТД)Док.НоваяСтрока();Док.Товар = Товар;Док.Количество = Количество;Док.Цена = Цена;Док.Сумма = Сумма;Док.НДС = НДС;Док.Кюар = ОбрезатьСтроку(Кюар, 35);Если ПустоеЗначение(ГТД) = 0 ТогдаДок.ГТД = ГТД;КонецЕсли;КонецПроцедуры
Когда один товар надо разбить на несколько строк
Отдельная неприятность — один товар, но несколько грузовых таможенных деклараций.
Например:
-
товар один;
-
общее количество — 15;
-
10 штук относятся к одной грузовой таможенной декларации;
-
5 штук — к другой.
В приходной накладной это уже не одна строка, а две. Количество понятно, но еще надо распределить сумму и НДС. Для промежуточных строк использовали пропорцию:
СуммаСтроки = Окр(СуммаБезНДС * КоличествоСтроки / Количество, 2);НДССтроки = Окр(СуммаНДС * КоличествоСтроки / Количество, 2);
А последней строке отдавали остаток:
СуммаСтроки = СуммаБезНДС - СуммаРазнесено;НДССтроки = СуммаНДС - НДСРазнесено;
Это обычный прием, чтобы не потерять копейки из-за округления.
Что делать с контрольными идентификационными знаками
Контрольные идентификационные знаки уже были реализованы до этих правок: каждый код маркировки создавал отдельную строку с количеством 1.
Эту часть трогать было рискованно. Поэтому логика осталась прежней, но к каждой строке добавилась грузовая таможенная декларация:
Кюар = ТекстXML(КодыКИЗ.ПолучитьУзел(НомерКИЗ));ГТД = ГТДДляЕдиницы(УзлыГТД,НомерКИЗ + 1,Количество,НаименованиеСтраны);ДобавитьСтрокуПрихода(Док, Товар, 1, Цена,СуммаСтроки, НДССтроки,Кюар, ГТД);
Получилось так: если товар маркирован, в документе по-прежнему будет строка на каждую единицу. Но теперь эта строка несет не только контрольный идентификационный знак, а еще и правильную грузовую таможенную декларацию.
Что проверял после правок
Нейросеть ускорила работу, но код все равно пришлось проверять обычным способом.
Я смотрел:
-
совпадают ли имена реквизитов с описанием конфигурации;
-
есть ли в базе нужные справочники:
КодыЕдиниц,ГТД,СтраныКод; -
не остались ли старые вызовы функций после изменения сигнатур;
-
не сломалась ли логика контрольных идентификационных знаков;
-
не затирается ли артикул пустым значением из XML-файла;
-
сходится ли баланс
Функция/КонецФункции,Процедура/КонецПроцедуры,Если/КонецЕсли; -
нет ли конструкций, которые могут быть сомнительны для 1С 7.7.
Старые среды не любят лишней смелости. Если можно написать проще и понятнее, лучше так и сделать.
Где нейросеть помогла, а где нет
Больше всего нейросеть помогла в рутине:
-
быстро прочитала большой модуль на встроенном языке 1С;
-
нашла места, куда встроить новую логику;
-
помогла сопоставить узлы XML-файла с реквизитами конфигурации;
-
набросала функции поиска и создания справочников;
-
подсказала варианты для отсутствующих единиц измерения.
Но учетные решения она за меня не принимала. Например, вопрос «создавать ли кор как новую единицу или пересчитывать в штуки» нельзя решить только по коду. Тут нужно понимать, как склад ведет остатки и что реально означает количество в документах поставщика.
В этом и есть нормальная роль нейросети в такой задаче: не заменить разработчика, а снять часть механической работы и быстрее довести до обсуждаемых вариантов.
Итог
После доработки обработка стала учитывать больше реальных случаев:
-
единицы измерения берутся из XML-файла;
-
отсутствующие единицы создаются автоматически;
-
АртикулТовпопадает в номенклатуру; -
создаются и заполняются грузовые таможенные декларации;
-
подтягивается страна происхождения;
-
строки разбиваются по грузовым таможенным декларациям;
-
контрольные идентификационные знаки и грузовые таможенные декларации работают вместе.
Вывод получился практический: нейросеть полезна в legacy-разработке, если давать ей не только задание, но и контекст — код, примеры данных, описание метаданных и ограничения. Тогда она действительно экономит время. Но проверка, учетная логика и ответственность за результат остаются на человеке.
ссылка на оригинал статьи https://habr.com/ru/articles/1047296/