При выгрузке или обработке данных через формат DBF с помощью встроенного объекта XBase часто возникает задача записи значений в серию однотипных колонок (например, SUM1, SUM2, ..., SUM30). Если формировать имя колонки динамически в строковой переменной, начинающие разработчики нередко сталкиваются с ошибками при попытке присвоить значение или сложить строку с числом. Разберем, почему возникают такие сложности и какими способами можно правильно адресовать динамические поля таблицы.
Проанализируем типичную ошибку при попытке динамической записи. Допустим, разработчик пытается получить доступ к полю следующим образом:
ИмяПоля = "SUM" + НомерСтолбца;
Поле = ИБ.Поля.Найти(ИмяПоля);
Поле = Поле + Элем.СуммаЛьготыОборот;
При выполнении этого кода платформа выдает ошибку: «Преобразование значения к типу Число не может быть выполнено». Выясним причину такого поведения:
ИБ.Поля содержит объекты метаописания структуры типа ПолеXBase. Метод Найти() возвращает описание колонки (свойства Имя, Тип, Длина, Точность), а не само значение в текущей строке. К объекту типа ПолеXBase нельзя прибавлять числовое значение.ИмяПоля = "ИБ.SUM" + НомерСтолбца; ИмяПоля = ИмяПоля + Число; приводит лишь к формированию текстовой строки (например, "ИБ.SUM1204.23"), так как интерпретатор 1С не выполняет динамическое вычисление выражений при обычном сложении строк."ИБ.SUM1", правильное имя поля — "SUM1").Рассмотрим наиболее простой, быстрый и лаконичный способ. Объект XBase поддерживает обращение к полям текущей записи через квадратные скобки. Внутри скобок можно передать вычисленную строку с именем поля:
// Формируем имя колонки динамически
ИмяКолонки = "SUM" + Строка(НомерСтолбца);
// Читаем текущее значение, прибавляем сумму и записываем обратно
ИБ[ИмяКолонки] = ИБ[ИмяКолонки] + Элем.СуммаЛьготыОборот;
ИБ.Записать();
Посмотрим, как это работает на практике. Если НомерСтолбца = 2, выражение ИБ["SUM2"] обращается напрямую к колонке SUM2 в текущей записи DBF-файла. Это избавляет от необходимости писать громоздкие конструкции с условиями Если ... ИначеЕсли для каждого из тридцати полей.
Разберем альтернативный вариант работы через методы самого объекта XBase. Платформа предоставляет специальные функции для чтения и изменения данных:
ПолучитьЗначениеПоля(<Поле>) — возвращает значение указанного поля в текущей записи. Параметр может принимать имя поля (тип Строка) или его порядковый номер (тип Число, начиная с 0).УстановитьЗначениеПоля(<Поле>, <Значение>) — устанавливает новое значение в текущую запись для указанного поля.Посмотрим на пример реализации с использованием этих методов:
ИмяКолонки = "SUM" + Формат(НомерСтолбца, "ЧГ=0");
ТекущаяСумма = ИБ.ПолучитьЗначениеПоля(ИмяКолонки);
ИБ.УстановитьЗначениеПоля(ИмяКолонки, ТекущаяСумма + Элем.СуммаЛьготыОборот);
ИБ.Записать();
Этот способ полностью эквивалентен обращению через квадратные скобки, но делает код более явным.
Если колонки в DBF-файле идут строго по порядку, мы можем обращаться к ним не по строковому имени, а по порядковому номеру (индексу). Обратите внимание: индексация полей в объекте XBase начинается с 0.
// Допустим, поля SUM1..SUM30 начинаются с индекса 2 в структуре DBF
ИндексПоля = (НомерСтолбца - 1) + Смещение;
// Обращение через квадратные скобки по числовому индексу:
ИБ[ИндексПоля] = ИБ[ИндексПоля] + Элем.СуммаЛьготыОборот;
// Либо через метод УстановитьЗначениеПоля:
// ИБ.УстановитьЗначениеПоля(ИндексПоля, ИБ.ПолучитьЗначениеПоля(ИндексПоля) + Элем.СуммаЛьготыОборот);
ИБ.Записать();
При формировании структуры и динамической записи данных в DBF обязательно учитывайте следующие технические особенности формата:
XBase должен быть позиционирован на конкретной строке (например, с помощью методов Первая(), Следующая(), Перейти() или после добавления новой строки методом Добавить()).ИБ.Записать().