Почему не заполняется сотрудник при загрузке данных из DBF в документ 1С и как это исправить?

Программист 1С v8.3 (Управляемые формы) 1С:Зарплата и Управление Персоналом IT и автоматизация бизнеса
← На главную

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

Основные причины проблемы при переносе данных из DBF

Проанализировав логику работы обработок чтения DBF-файлов и поиска элементов в справочниках 1С, можно выделить три ключевые ошибки:

  1. Расхождение типов данных и форматов кодов: В файлах DBF табельный номер сотрудника (поле TABNOM) часто хранится как числовое значение (например, 10004). В справочнике Сотрудники 1С код обычно имеет строковый тип с лидирующими нулями (например, "0000010004") или содержит префиксы организации. Прямой метод НайтиПоКоду(ДБФ.TABNOM) в этом случае возвращает пустую ссылку.
  2. Ошибки при работе с табличными частями: Некорректное обращение к строкам документа, когда одна часть реквизитов записывается в добавленную строку табличной части Начисления, а ссылка на сотрудника — в новую строку табличной части Удержания.
  3. Лишний переход по записям в цикле обхода DBF: Использование двойного вызова метода ДБФ.Следующая() внутри одного цикла приводит к пропуску строк файла и некорректному считыванию значений.

Способ 1. Форматирование табельного номера с учетом длины кода

Если в справочнике сотрудников используется стандартная нумерация с лидирующими нулями, разберем, как привести числовое значение из DBF к строковому формату нужной длины. Для этого применим функцию Формат() и обратимся к метаданным справочника:


ДлинаКода = Метаданные.Справочники.Сотрудники.ДлинаКода;
ТабельныйНомер = Формат(ДБФ.TABNOM, "ЧЦ=" + ДлинаКода + "; ЧВН=; ЧГ=0");
Сотр1 = Справочники.Сотрудники.НайтиПоКоду(ТабельныйНомер);

Если Не Сотр1.Пустая() Тогда
    ТекСтрока.Сотрудник = Сотр1;
КонецЕсли;

Параметр ЧВН= отвечает за вывод незначащих нулей, а ЧГ=0 отключает группировку тысяч, что позволяет получить точное соответствие коду 1С.

Способ 2. Предварительная выгрузка сотрудников в таблицу значений (Рекомендуемый)

Вызов метода НайтиПоКоду() на каждой итерации обхода DBF-файла существенно замедляет работу системы. Наиболее эффективным решением является предварительная выборка всех действующих сотрудников запросом, с последующим поиском в памяти по очищенному числовому коду.

Рассмотрим пошагово реализацию этого алгоритма:

Шаг 1. Сформируем запрос и заполним дополнительную колонку с числовым представлением кода:


Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |	Сотрудники.Код КАК Код,
    |	Сотрудники.Ссылка КАК Сотрудник,
    |	0 КАК КодЧислом
    |ИЗ
    |	Справочник.Сотрудники КАК Сотрудники
    |ГДЕ
    |	НЕ Сотрудники.ПометкаУдаления
    |	И НЕ Сотрудники.ВАрхиве";

ТаблицаСотрудников = Запрос.Выполнить().Выгрузить();

// Приводим строковые коды к числу для сопоставления с DBF
Для Каждого СтрокаТЗ Из ТаблицаСотрудников Цикл
    Попытка
        СтрокаТЗ.КодЧислом = Число(СтрокаТЗ.Код);
    Исключение
        // Если код содержит буквы или спецсимволы, оставляем 0
        СтрокаТЗ.КодЧислом = 0;
    КонецПопытки;
КонецЦикла;

Шаг 2. Реализуем цикл чтения DBF и заполнения документа:


ДБФ = Новый XBase;
ДБФ.Кодировка = КодировкаXBase.OEM;
ДБФ.ОткрытьФайл(ПутьКФайлу);

Если Не ДБФ.Открыта() Тогда
    Сообщить("Не удалось открыть файл DBF!");
    Возврат;
КонецЕсли;

Док = Документы.НачислениеЗарплаты.СоздатьДокумент();
Док.Дата = ТекущаяДата();

ДБФ.Первая();
Пока ДБФ.ВКонце() = 0 Цикл
    
    // Создаем строку в табличной части Начисления
    ТекСтрока = Док.Начисления.Добавить();
    ТекСтрока.Результат = ДБФ.Summa;
    
    // Ищем сотрудника в ранее подготовленной таблице значений по числовому коду
    СтрокаНайдена = ТаблицаСотрудников.Найти(ДБФ.TABNOM, "КодЧислом");
    Если СтрокаНайдена <> Неопределено Тогда
        ТекСтрока.Сотрудник = СтрокаНайдена.Сотрудник;
    КонецЕсли;

    ДБФ.Следующая();
КонецЦикла;

Док.Записать();
ДБФ.ЗакрытьФайл();

Важные рекомендации по заполнению документов начисления

Выясним еще несколько важных нюансов, которые необходимо учитывать при программном создании документов начисления зарплаты:

← На главную