Как правильно заполнить табличную часть документа при импорте из DBF в 1С 7.7

Программист 1С v7.7 1C:Бухгалтерия Бухгалтерский учет IT и автоматизация бизнеса
← На главную

При переносе данных и разработке обработок загрузки из внешних источников (например, DBF-файлов учетных программ) часто возникает задача создания единого документа с несколькими строками вместо дробления данных на отдельные документы. В платформе 1С:Предприятие 7.7 начинающие разработчики нередко сталкиваются с ошибками при переходе от заполнения реквизитов шапки к наполнению табличной части. Разберем типичную проблему, проанализируем причины ее возникновения и рассмотрим корректный алгоритм формирования строк документа.

В чем заключалась ошибка в исходном коде

Проанализируем фрагмент кода, который вызвал затруднение при попытке сформировать акт с двумя строками (одна строка со ставкой НДС, вторая — льготируемая без НДС):


ДокАкт.ВыбратьСтроки;
Пока ДокАкт.ПолучитьСтроку = 1 Цикл
    ДокАкт.НоваяСрока;
    // Заполнение реквизитов первой строки...
    ДокАкт.НоваяСтрока;
    // Заполнение реквизитов второй строки...
    ДокАкт.Записать;
    ДокАкт.Провести;
    Прервать;
КонецЦикла;

В приведенном коде допущены критические логические и синтаксические ошибки:

  1. Попытка обхода несуществующих строк: методы ВыбратьСтроки() и ПолучитьСтроку() предназначены исключительно для чтения уже записанных строк существующего документа. У только что созданного через Новый() документа табличная часть пуста. Метод ПолучитьСтроку() сразу возвращает 0, тело цикла Пока ... Цикл не выполняется ни разу, и строки вообще не создаются.
  2. Синтаксическая опечатка: вызов ДокАкт.НоваяСрока; содержит опечатку в названии метода (пропущена буква «т»), что привело бы к ошибке времени выполнения.
  3. Преждевременная запись и прерывание: вызовы Записать() и Провести() были помещены внутрь цикла до завершения обработки структуры данных.

Правильный порядок работы с табличной частью документа

Для добавления строк в табличную часть нового документа цикл перебора строк не требуется. Достаточно последовательно вызывать метод НоваяСтрока(), заполнять реквизиты текущей строки и только после добавления всех строк выполнять запись документа.

Рассмотрим пошагово правильную структуру кода:


Если (ПустоеЗначение(ДБФ.DATA_VYDAC) = 0) и ((ДБФ.LG_CH_TC <> 0) и (ДБФ.ST_OBL_NDS <> 0)) Тогда
    
    // 1. Инициализация нового документа и заполнение шапки
    ДокАкт.Новый();
    ДокАкт.НомерДок = СокрЛП(Строка(ДБФ.REG_NOM));
    ДокАкт.ДатаДок  = ДБФ.DATA_VYDAC;
    
    // Включение режима табличной части (если предусмотрено конфигурацией)
    ДокАкт.ФлагТаблица = 1;
    
    СпрВидДокЭСЧФ.НайтиПоКоду("606");
    ДокАкт.ВидДокументаЭСЧФ = СпрВидДокЭСЧФ.ТекущийЭлемент();
    ДокАкт.ВидОказанияУслуг = Перечисление.ВидОказанияУслуг.ОказаниеУслуг;
    ДокАкт.СчетПокупателя   = СчетПоКоду("62.1.1");
    ДокАкт.СчетРеализации   = СчетПоКоду("90.1.1");
    
    // Поиск контрагента по УНН
    Если СпрКонтр.НайтиПоРеквизиту("УНН", ДБФ.UNN_ZAKAZC, 1) = 1 Тогда
        ДокАкт.Контрагент = СпрКонтр.ТекущийЭлемент();
    Иначе
        Предупреждение("У заказчика неверно указан УНН в акте №" + СокрЛП(Строка(ДБФ.REG_NOM)));
        Возврат;
    КонецЕсли;
    
    // Поиск договора по номеру
    СпрДог.ИспользоватьВладельца(СпрКонтр.ТекущийЭлемент());
    Если СпрДог.НайтиПоРеквизиту("НомерДоговора", СокрЛП(ДБФ.REG_NOM), 1) = 1 Тогда
        ДокАкт.Договор = СпрДог.ТекущийЭлемент();
    КонецЕсли;
    
    // Определение аналитики (субконто)
    ДокАкт.НазначитьТип("шСубконто1", "Справочник.ВидыДеятельности");
    ДокАкт.шСубконто1 = ВидДеят.ТекущийЭлемент();
    
    ДокАкт.НазначитьТип("шСубконто2", "Справочник.ВидыВариантовРеализации");
    Если (СтрЧислоВхождений(Строка(ДБФ.REG_NOM), "-42") = 1) или (СтрЧислоВхождений(Строка(ДБФ.REG_NOM), "-51") = 1) Тогда
        ВидВарРеализ.НайтиПоКоду(2);
    Иначе
        ВидВарРеализ.НайтиПоКоду(1);
    КонецЕсли;
    ДокАкт.шСубконто2 = ВидВарРеализ.ТекущийЭлемент();
    
    СпрУслуги.НайтиПоКоду(СокрЛП(Строка(ДБФ.REG_NOM)));
    ДокАкт.шУслуга = СпрУслуги.ТекущийЭлемент();
    
    // 2. Добавление первой строки (облагаемая НДС часть)
    ДокАкт.НоваяСтрока();
    ДокАкт.НаименованиеУслуги = ДокАкт.шУслуга;
    ДокАкт.Субконто1          = ДокАкт.шСубконто1;
    ДокАкт.Субконто2          = ДокАкт.шСубконто2;
    ДокАкт.СуммаБезНДС        = ДБФ.ST_OBL_NDS;
    ДокАкт.СуммаНДС           = ДБФ.SUMMA_NDS;
    
    СтНДС.НайтиПоКоду("1"); // Ставка НДС 18% или 20%
    ДокАкт.СтавкаНДС          = СтНДС.ТекущийЭлемент();
    ДокАкт.СуммаСНДС          = ДБФ.ST_OBL_NDS + ДБФ.SUMMA_NDS;
    ДокАкт.СуммаВсего         = ДБФ.ST_OBL_NDS + ДБФ.SUMMA_NDS;
    
    // 3. Добавление второй строки (льготируемая часть без НДС)
    ДокАкт.НоваяСтрока();
    ДокАкт.НаименованиеУслуги = ДокАкт.шУслуга;
    ДокАкт.Субконто1          = ДокАкт.шСубконто1;
    ДокАкт.Субконто2          = ДокАкт.шСубконто2;
    ДокАкт.СуммаБезНДС        = ДБФ.LG_CH_TC;
    ДокАкт.СуммаНДС           = 0;
    
    СтНДС.НайтиПоКоду("5"); // Без НДС
    ДокАкт.СтавкаНДС          = СтНДС.ТекущийЭлемент();
    ДокАкт.СуммаСНДС          = ДБФ.LG_CH_TC;
    ДокАкт.СуммаВсего         = ДБФ.LG_CH_TC;
    
    // 4. Запись и проведение готового документа со всеми строками
    ДокАкт.Записать();
    ДокАкт.Провести();
    
КонецЕсли;

Важные особенности и рекомендации при разработке импорта в 1С 7.7

Разберем ключевые технические нюансы, которые необходимо учитывать при работе с объектами метаданных и файлами DBF:

  1. Очистка строк при повторной перезаписи: если документ создается не с нуля через Новый(), а перезаписывается существующий объект, перед наполнением необходимо очистить его табличную часть. В платформе 7.7 нет метода Очистить(), поэтому используется цикл:
    
    Пока ДокАкт.КоличествоСтрок() > 0 Цикл
        ДокАкт.УдалитьСтроку(1);
    КонецЦикла;
    
  2. Проверка дат из внешнего источника: конструкция СтрДлина(число(ДБФ.DATA_VYDAC)) нестабильна, так как передача нечисловых символов или пустой строки приведет к ошибке приведения типов. Безопаснее проверять заполненность даты через функцию ПустоеЗначение(ДБФ.DATA_VYDAC) = 0.
  3. Суммы в шапке документа: если реквизит ФлагТаблица = 1 переключает видимость табличной части, типовые алгоритмы проведения или модули выгрузки ЭСЧФ могут по-прежнему считывать итоговые суммы из реквизитов шапки (шСуммаВсего, шСуммаНДС). При программном формировании документа рекомендуется явно заполнять реквизиты шапки суммой по всем добавленным строкам.
  4. Оптимизация поиска: инициализацию вспомогательных объектов справочников (СпрКонтр = СоздатьОбъект("Справочник.Контрагенты");) следует выполнять до начала цикла обхода DBF-файла. Это существенно ускорит выполнение загрузки больших объемов данных.
← На главную