Skip to content

Latest commit

 

History

History
515 lines (424 loc) · 39.6 KB

ЗагрузкаФайлаЧерезТабличныйДокумент.md

File metadata and controls

515 lines (424 loc) · 39.6 KB

Подсистема загрузки файлов Excel через табличный документ

Предназначена для универсальной загрузки Excel-файлов (csv-файлов) через табличный документ. Преобразование происходит в два этапа:

  • Чтение файла и сопоставление его колонок с "макетом" - таблицей значений, где описаны свойства колонок и порядок конвертации;
  • Конвертация строковых значений в соответствии с "макетом": поиск ссылок для ссылочных объектов, конвертация базовых типов данных (Число, Дата, Булево).

Результатом конвертации будет являтся таблица значений, сформированная по описанным в "макете" правилам.

Описание свойств колонок файла ("макета")

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

НоваяСтрока = ТаблицаСвойств.Добавить();
НоваяСтрока.ИмяКолонки	= "Номенклатура";

НоваяСтрока = ТаблицаСвойств.Добавить();
НоваяСтрока.ИмяКолонки	= "Артикул";

НоваяСтрока = ТаблицаСвойств.Добавить();
НоваяСтрока.ИмяКолонки	= "Наименование";

то первая колонка файла всегда будет распознана как номенклатура, не смотря на то, что там может быть значение другого типа (например, контрагент).

Если установлен вариант "по наименованию", то строка файла с номером начальной строки чтения будет идентифицирована как шапка таблицы. Колонки шапки таблицы будут проанализированы и сопоставлены по наименованию с таблицей свойств. Имя колонки файла должно быть равно либо свойству "ИмяВТабДоке", либо свойству "ИмяКолонки". В противном случае, колонка будет не идентифицирована. Все неидентифицированные колонки файла будут удалены из табличного документа, их значения не загрузятся из файла и не будут доступны для последующей обработки.

Чтобы инициализировать таблицу свойств необходимо вызвать функцию в зависимости от контекста выполнения кода:

С клиента:
ТаблицаСвойств = пбп_ЗагрузкаФайлаЧерезТабличныйДокументВызовСервера.ИнициализироватьТаблицуСоСвойствамиКолонок()
С сервера:
ТаблицаСвойств = пбп_ЗагрузкаФайлаЧерезТабличныйДокументСервер.ИнициализироватьТаблицуСоСвойствамиКолонок()

Таблица свойств содержит следующие колонки строкового типа:

  1. ИмяКолонки - имя колонки в итоговой таблице значений для последующего обращения к ней;
  2. ИмяВТабДоке - имя колонки в файле. Свойство учитывается при сопоставлении колонок по наименованию. Если не заполнено, то имя колонки считается равным значению из "ИмяКолонки", например:
// Здесь ИмяВТабДоке не указано, поэтому колонка будет искаться по значению "ЕдиницаХранения"
НоваяСтрока = ТаблицаСвойств.Добавить();
НоваяСтрока.ИмяКолонки	= "ЕдиницаХранения";
// Здесь ИмяВТабДоке указано, поэтому колонка будет искаться по значению "Единица хранения"
НоваяСтрока = ТаблицаСвойств.Добавить();
НоваяСтрока.ИмяКолонки	= "ЕдиницаХранения";
НоваяСтрока.ИмяВТабДоке	= "Единица хранения";
  1. Группа - имя колонки "группы" ячеек. Под группой подразумевается объединение ячеек строкой выше в шапке таблицы. Например, в примере ниже группой колонок будет являтся "Номенклатура":
Номенклатура
Наименование Артикул Единица хранения
Ложка 0000001 шт

Тогда инициализация группы в свойствах колонок будет выглядеть следующим образом:

ГруппаЯчеек = "Номенклатура";

НоваяСтрока = ТаблицаСвойств.Добавить();
НоваяСтрока.ИмяКолонки	= "Наименование";
НоваяСтрока.Группа      = ГруппаЯчеек;

НоваяСтрока = ТаблицаСвойств.Добавить();
НоваяСтрока.ИмяКолонки	= "Артикул";
НоваяСтрока.Группа      = ГруппаЯчеек;

НоваяСтрока = ТаблицаСвойств.Добавить();
НоваяСтрока.ИмяКолонки	= "ЕдиницаХранения";
НоваяСтрока.ИмяВТабДоке	= "Единица хранения";
НоваяСтрока.Группа      = ГруппаЯчеек;
  1. ТипЗначения - тип значения, в который будет конвертировано значение колонки. Может принимать значения базовых типов: Число, Булево, Дата,- так и ссылочные типы:
НоваяСтрока = ТаблицаСвойств.Добавить();
НоваяСтрока.ИмяКолонки	= "Наименование";
НоваяСтрока.ТипЗначения = "Строка";

НоваяСтрока = ТаблицаСвойств.Добавить();
НоваяСтрока.ИмяКолонки	= "ЕдиницаХранения";
НоваяСтрока.ТипЗначения = "СправочникСсылка.УпаковкиЕдиницыИзмерения";
НоваяСтрока.ПолеПоиска1 = "Наименование";

Для конвертации значений "булево" необходимо указывать строковое представление ИСТИНА (по умолчанию, если представление не указано, проверка на "да" и "истина"), для конвертации даты в параметрах чтения файла ключ КонвертироватьДаты должен быть Истина (подробно см. в главе Параметры чтения файла). Для конвертации ссылочных типов необходимо заполнить поля поиска. В указанном выше примере единица хранения будет искаться по полю "наименование". 5) ПолеПоиска1, ПолеПоиска2, ПолеПоиска3 - название реквизита объекта, по которому будет произведен поиск значения ссылочного типа. 6) ОператорУсловия - оператор сравнения в условии соединения таблицы с типом значения между полями поиска. По умолчанию "ИЛИ", также может равняться "И" или "ВИРТ". Например, если в колонке файла "Контрагент" может быть указан либо ИНН, либо ОКПО, либо наименование, и, соответственно, поиск должен производится по этим полям объекта с указанным приоритетом (высший ИНН, низший - наименование), то указываем свойства в следующем порядке:

НоваяСтрока = ТаблицаСвойств.Добавить();
НоваяСтрока.ИмяКолонки	= "Контрагент";
НоваяСтрока.ТипЗначения = "СправочникСсылка.Контрагенты";
НоваяСтрока.ПолеПоиска1 = "ИНН";
НоваяСтрока.ПолеПоиска2 = "КодПоОКПО";
НоваяСтрока.ПолеПоиска3 = "Наименование";

На выходе в итоговом запросе конвертации значений ссылочных типов получится следующее соединение:

ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Контрагенты КАК Контрагенты1
   ПО ВходнаяТаблица.Контрагент <> "" И ВходнаяТаблица.Контрагент <> 0
      И (ВходнаяТаблица.Контрагент = Контрагенты1.ИНН
      ИЛИ ВходнаяТаблица.Контрагент = Контрагенты1.КодПоОКПО
      ИЛИ ВходнаяТаблица.Контрагент = Контрагенты1.Наименование)

При использовании оператора "И" имена полей поиска должны равняться именам колонок обрабатываемой таблицы. Например: если в свойствах макета у колонки заполнен тип ДокументСсылка., ПолеПоиска1 = "Номер", а ПолеПоиска2 = "Дата" И ОператорУсловия = "И", тогда таблица построителя должна иметь колонки "Номер", где лежит номер документа и "Дата", где лежит дата документа:

Номер Дата Контрагент ...
000000001 01.01.2023 ООО "Ромашка" ...
НоваяСтрока = ТаблицаСвойств.Добавить();
НоваяСтрока.ИмяКолонки	= "Реализация";
НоваяСтрока.ТипЗначения = "ДокументСсылка.РеализацияТоваровУслуг";
НоваяСтрока.ПолеПоиска1 = "Номер";
НоваяСтрока.ПолеПоиска2 = "Дата";
НоваяСтрока.ОператорУсловия = "И";

Оператор "ВИРТ" предназначен для инициализации "виртуальных" полей ссылочных типов (которые не входят в логику оператора "И"), т.е. которых нет в исходном файле. Например, если колонки "Номенклатура" в файле нет, но есть одно из полей поиска номенклатуры, допустим "Артикул", то используя оператор "ВИРТ" в итоговой таблице мы получим ссылку на номенклатуру, полученную поиском по артикулу:

НоваяСтрока = ТаблицаСвойств.Добавить();
НоваяСтрока.ИмяКолонки	= "Номенклатура";
НоваяСтрока.ТипЗначения	= "СправочникСсылка.Номенклатура";
НоваяСтрока.ПолеПоиска1	= "Артикул";
НоваяСтрока.ОператорУсловия	= "ВИРТ";

В этом примере номенклатуру также можно найти с помощью оператора "ИЛИ" напрямую по артикулу

НоваяСтрока = ТаблицаСвойств.Добавить();
НоваяСтрока.ИмяКолонки  = "Артикул";
НоваяСтрока.ТипЗначения = "СправочникСсылка.Номенклатура";
НоваяСтрока.ПолеПоиска1 = "Артикул";

но в этом случае имя колонки "Артикул" будет зарезервировано ссылкой на номенклатуру. Если нужно загрузить оба поля: и номенклатуру, и артикул,- то нужно объявить оба поля, одно из которых будет виртуальным, а другое загружаться из файла как строковое значение:

НоваяСтрока = ТаблицаСвойств.Добавить();
НоваяСтрока.ИмяКолонки	= "Номенклатура";
НоваяСтрока.ТипЗначения	= "СправочникСсылка.Номенклатура";
НоваяСтрока.ПолеПоиска1	= "Артикул";
НоваяСтрока.ОператорУсловия	= "ВИРТ";

НоваяСтрока = ТаблицаСвойств.Добавить();
НоваяСтрока.ИмяКолонки	= "Артикул";
НоваяСтрока.ТипЗначения	= "Строка";
  1. ФункцияПреобразования - имя экспортной функции в программном интерфейсе, которая будет вызвана для конвертации значения. Допустим, нам необходимо убрать лидирующие нули в колонке. Тогда в серверном общем модуле ("ТестЗагрузкиФайлаИзТабличногоДокумента") создаем экспортную функцию УбратьЛидирующиеНули с параметром "ВходящееЗначение" (в него придет строковое значение ячейки файла):
Функция УбратьЛидирующиеНули(ВходящееЗначение) Экспорт
	Возврат СтроковыеФункцииКлиентСервер.УдалитьПовторяющиесяСимволы(ВходящееЗначение, "0");	
КонецФункции

А в свойствах колонки прописываем отношение колонки к этой функции:

НоваяСтрока = ТаблицаСвойств.Добавить();
НоваяСтрока.ИмяКолонки	= "Наименование";
НоваяСтрока.ТипЗначения = "Строка";
НоваяСтрока.ФункцияПреобразования = "ТестЗагрузкиФайлаИзТабличногоДокумента.УбратьЛидирующиеНули";
  1. ФорматДаты - формат даты строкой. Если указан, то строковое значение будет конвертироваться в дату по указаному формату. Сам формат представляет собой строку с номерами разрядов через разделитель "_" (например, "1_1_2"). Первый разряд показывает какой разделитель используется в представлении даты, второй разряд показывает положение дня, месяца и года по отношению друг к другу, третий разряд показывает представление времени в дате. Если номер формата "0_0_0" - преобразование происходит из функции XMLЗначение (ISO формат даты вида "2023-12-31T18:30:51").
  • Первый разряд принимает значения:
    • 1 - разделитель ".";
    • 2 - "/";
    • 3 - "-";
    • 4 - " ";
  • Второй разряд принимает значения:
    • 0 - месяц, день, год
    • 1 - год идет первым, потом месяц и день;
    • 2 - сначала день, потом месяц и год;
    • 3 - сначала день, месяц СТРОКОЙ и год;
  • Третий разряд принимает значения:
    • 0 - время отсутствует;
    • 1 - время стандартное, 24-часовое представление
    • 2 - время в 12-ти часовом представлении (AM / PM)

Примеры номеров форматов:

  • 1_1_2 - "2021.12.01 8:10 PM";
  • 2_1_0 - "2021/12/01";
  • 1_3_1 - "01.дек.2021 20:10";
  • 3_1_1 - "2021-12-01 20:10"

Если формат даты колонки не указан в свойствах, а тип колонки "Дата", то ее формат будет определен по первому значению колонки в процессе конвертации строковых значений по типам, но только в том случае, если в параметрах чтения файла ключ КонвертироватьДаты равен Истина. Исключением из данного правила являются даты, где месяц указывается первым (например, 12/31/3999). В этом случае ФорматДаты колонки должен быть заполнен явным образом. В этом примере номер формата даты будет равен "2_0_0":

НоваяСтрока = ТаблицаСвойств.Добавить();
НоваяСтрока.ИмяКолонки	= "ДатаДокумента";
НоваяСтрока.ТипЗначения = "Дата";
НоваяСтрока.ФорматДаты = "2_0_0"; // значение вида "12/31/3999"

Параметры чтения файла

Параметры влияют на чтение данных из файла и их конвертацию. Для того чтобы указать параметры чтения файла необходимо вызвать функцию ПолучитьПараметрыЧтенияФайла():

ПараметрыЧтения = пбп_ЗагрузкаФайлаЧерезТабличныйДокументСервер.ПолучитьПараметрыЧтенияФайла();

При вызове функции клиентской загрузки из XLS (общий модуль "пбп_ЗагрузкаФайлаЧерезТабличныйДокументКлиент") параметры чтения передаются параметрами функции (пример см. в главе Пример вызова с клиента).

Структура параметров имеют следующие ключи:

  1. НазваниеЛиста - Строка - название листа в исходном файле;
  2. НомерСтроки - Число - начальный номер строки, с которой начинается чтение файла. Обычно, это шапка таблицы. Строки до нее обрезаются;
  3. СопоставлениеПоНаименованию - Булево - если Истина, то колонки будут сравниваться по наименованию; если Ложь, то по порядку, указанном в таблице свойств колонок (подробно см. в начале главы Описание свойств колонок файла). По умолчанию Ложь;
  4. КонвертироватьДаты - Булево - если Истина, то колонки с типом Дата будут конвертироваться автоматически из строкового значения в дату, по умолчанию Истина;
  5. ВыдаватьОшибкуПриОтсутствииЛиста - Булево - если Истина, то при отсутствии листа с наименованием, указанном в ключе "НазваниыеЛиста", в файле обработка файла будет прервана с ошибкой. По умолчанию Ложь;
  6. ЗначениеИстина - Строка - строковое представление значения ИСТИНА для колонок с типом булево (например, "Y" или "Да"). Если не заполнено, то проверяется на равенство строке "истина" или "да";
  7. ОставитьСтроковыеЗначения - если Истина, то оставляет колонки с исходными строковыми значениями конвертируемых типов (Булево, Число, Дата) с постфиксом "Строкой". В противном случае удаляет их после конвертации. По умолчанию Ложь;
  8. ИскатьПомеченныеНаУдаление - если Истина, то при поиске ссылок на объекты игнорирует пометку на удаление. В противном случае, помеченные на удаление не будут учитываться. По умолчанию Истина.

Примеры вызова загрузки файла

После изучения правил заполенения таблицы свойств колонок и параметров чтения можно рассмотреть вызовы загрузки файла на примерах. Дан следующий Excel-файл с данными реализаций товаров и услуг:

Номер Дата Номенклатура (Артикул) Цена Количество Сумма
000000001 01.01.2023 10:30:13 123 100 2 200
000000001 01.01.2023 10:30:13 789 300 1 300
000000002 01.01.2023 15:14:01 456 200 4 800
000000003 02.01.2023 09:46:10 123 100 15 1500

Пример вызова с клиента

&НаКлиенте
Асинх Процедура ЗагрузитьXLS(Команда)

   // Заполняем таблицу свойств колонок. Так как свойства лежат в таблице значений, на клиент возвращаем адрес временного хранилища с ТЗ
   АдресХранилища = ПолучитьСтруктуруЗагружаемогоОбъекта();

   ИмяСтраницы = "Лист1";
   НомерПервойСтроки = 2;

   // Заполняем параметры чтения
   ПараметрыЧтения = пбп_ЗагрузкаФайлаЧерезТабличныйДокументКлиент.ПолучитьПараметрыЧтенияФайла();
   ПараметрыЧтения.НазваниеЛиста               = ИмяСтраницы;
   ПараметрыЧтения.НомерСтроки                 = НомерПервойСтроки;
   ПараметрыЧтения.СопоставлениеПоНаименованию = Истина;
   ПараметрыЧтения.ЗначениеИстина              = "Y";

   // Переменная ИД равняется адресу итоговой таблицы во временном хранилище
   ИД = Ждать пбп_ЗагрузкаФайлаЧерезТабличныйДокументКлиент.ЗагрузитьИзXLS(АдресХранилища, ПараметрыЧтения);

   Если ЗначениеЗаполнено(ИД) Тогда
      ЗагрузкаНаСервере(ИД);
   КонецЕсли; 

КонецПроцедуры

&НаСервере
Функция ПолучитьСтруктуруЗагружаемогоОбъекта()

   СтруктураКолонок = пбп_ЗагрузкаФайлаЧерезТабличныйДокументСервер.ИнициализироватьТаблицуСоСвойствамиКолонок();

   НоваяСтрока = СтруктураКолонок.Добавить();
   НоваяСтрока.ИмяКолонки  = "Реализация";
   НоваяСтрока.ТипЗначения = "ДокументСсылка.РеализацияТоваровУслуг";
   НоваяСтрока.ПолеПоиска1 = "Номер";
   НоваяСтрока.ПолеПоиска2 = "Дата";
   НоваяСтрока.ОператорУсловия = "И";

   НоваяСтрока = СтруктураКолонок.Добавить();
   НоваяСтрока.ИмяКолонки  = "Номер";
   НоваяСтрока.ТипЗначения = "Строка";

   НоваяСтрока = СтруктураКолонок.Добавить();
   НоваяСтрока.ИмяКолонки  = "Дата";
   НоваяСтрока.ТипЗначения = "Дата";

   НоваяСтрока = СтруктураКолонок.Добавить();
   НоваяСтрока.ИмяКолонки  = "Номенклатура";
   НоваяСтрока.ИмяВТабДоке = "Номенклатура (Артикул)";
   НоваяСтрока.ТипЗначения = "СправочникСсылка.РеализацияТоваровУслуг";
   НоваяСтрока.ПолеПоиска1 = "Артикул";

   НоваяСтрока = СтруктураКолонок.Добавить();
   НоваяСтрока.ИмяКолонки  = "Цена";
   НоваяСтрока.ТипЗначения = "Число";

   НоваяСтрока = СтруктураКолонок.Добавить();
   НоваяСтрока.ИмяКолонки  = "Количество";
   НоваяСтрока.ТипЗначения = "Число";

   НоваяСтрока = СтруктураКолонок.Добавить();
   НоваяСтрока.ИмяКолонки  = "Сумма";
   НоваяСтрока.ТипЗначения = "Число";

   АдресХранилища = ПоместитьВоВременноеХранилище(СтруктураКолонок, Новый УникальныйИдентификатор);

   Возврат АдресХранилища;

КонецПроцедуры

&НаСервере
Процедура ЗагрузкаНаСервере(ИД)
   ТЗ = ПолучитьИзВременногоХранилища(ИД);

   // Пост-обработка полученных данных
   // ...
КонецПроцедуры

Пример вызова с сервера

Процедура ЗагрузитьXSL(ДвоичныеДанныеФайла, Расширение)

   СтруктураКолонок = ПолучитьСтруктуруЗагружаемогоОбъекта();

   // Инициализируем параметры чтения для дальнейшей передачи
   // Для серверного контекста вызывается функция из серверного модуля
   ПараметрыЧтения = пбп_ЗагрузкаФайлаЧерезТабличныйДокументСервер.ПолучитьПараметрыЧтенияФайла();
   ПараметрыЧтения.НазваниеЛиста                    = "Лист1";
   ПараметрыЧтения.НомерСтроки                      = 2;
   ПараметрыЧтения.СопоставлениеПоНаименованию      = Истина;
   ПараметрыЧтения.КонвертироватьДаты               = Истина;
   ПараметрыЧтения.ВыдаватьОшибкуПриОтсутствииЛиста = Ложь;
   ПараметрыЧтения.ЗначениеИстина                   = "Y";
   ПараметрыЧтения.ОставитьСтроковыеЗначения        = Ложь;
   ПараметрыЧтения.ИскатьПомеченныеНаУдаление       = Ложь;
   
   // Помещаем файл в хранилище на сервере
   АдресВХранилище = ПоместитьВоВременноеХранилище(ДвоичныеДанныеФайла, Новый УникальныйИдентификатор);
   ТаблицаДанных = пбп_ЗагрузкаФайлаЧерезТабличныйДокументСервер
      .КонвертироватьДанныеТабличногоДокументаВТаблицуЗначений(
      АдресВХранилище, Расширение, ТаблицаСвойств, ПараметрыЧтения);
   
   // Для не найденных значений в итоговой таблице будут Null. Уберем их
   пбп_ЗагрузкаФайлаЧерезТабличныйДокументСервер.ТаблицаЗначенийБезNull(ТаблицаДанных);

   // Пост-обработка полученных данных
   // ...

КонецПроцедуры

Функция ПолучитьСтруктуруЗагружаемогоОбъекта()

   СтруктураКолонок = пбп_ЗагрузкаФайлаЧерезТабличныйДокументСервер.ИнициализироватьТаблицуСоСвойствамиКолонок();

   НоваяСтрока = СтруктураКолонок.Добавить();
   НоваяСтрока.ИмяКолонки  = "Реализация";
   НоваяСтрока.ТипЗначения = "ДокументСсылка.РеализацияТоваровУслуг";
   НоваяСтрока.ПолеПоиска1 = "Номер";
   НоваяСтрока.ПолеПоиска2 = "Дата";
   НоваяСтрока.ОператорУсловия = "И";

   НоваяСтрока = СтруктураКолонок.Добавить();
   НоваяСтрока.ИмяКолонки  = "Номер";
   НоваяСтрока.ТипЗначения = "Строка";

   НоваяСтрока = СтруктураКолонок.Добавить();
   НоваяСтрока.ИмяКолонки  = "Дата";
   НоваяСтрока.ТипЗначения = "Дата";

   НоваяСтрока = СтруктураКолонок.Добавить();
   НоваяСтрока.ИмяКолонки  = "Номенклатура";
   НоваяСтрока.ИмяВТабДоке = "Номенклатура (Артикул)";
   НоваяСтрока.ТипЗначения = "СправочникСсылка.РеализацияТоваровУслуг";
   НоваяСтрока.ПолеПоиска1 = "Артикул";

   НоваяСтрока = СтруктураКолонок.Добавить();
   НоваяСтрока.ИмяКолонки  = "Цена";
   НоваяСтрока.ТипЗначения = "Число";

   НоваяСтрока = СтруктураКолонок.Добавить();
   НоваяСтрока.ИмяКолонки  = "Количество";
   НоваяСтрока.ТипЗначения = "Число";

   НоваяСтрока = СтруктураКолонок.Добавить();
   НоваяСтрока.ИмяКолонки  = "Сумма";
   НоваяСтрока.ТипЗначения = "Число";

   Возврат СтруктураКолонок;

КонецПроцедуры

Чтение CSV-файла

Порядок вызова функций для чтения CSV-файлов будет немного отличаться от аналогичного чтения Excel-файлов. Подсистема распознает два вида заполнения файлов: где есть разделители, и где разделители условны, а значения колонок находятся на определенных позициях строки, например:

123 Номенклатура №1 шт

456 Номенклатура №2 исшт

Во второй строке видно, что разделитель между наименованием номенклатуры и наименованием единицы измерения ("шт") отсутствует, но, очевидно, это разные колонки.

Для файлов, где есть разделители, параметры чтения от Excel отличаться не будут, за исключением того, что чтение csv-файлов происходит в строгом порядке, указанном в таблице свойств колонок. Для файлов, где значения колонок стоят на определенных позициях строки, для каждой колонки необходимо заполнить начальный символ в строке файла и длину значения. Для этого свойства таблицы необходимо инициализоровать не посредством вызова функции "ИнициализироватьТаблицуСоСвойствамиКолонок", а посредством вызова "ИнициализироватьТаблицуСоСвойствамиCSV". Для выше указанного файла заполнение будет выглядеть следующим образом:

СтруктураКолонок = пбп_ЗагрузкаФайлаЧерезТабличныйДокументСервер.ИнициализироватьТаблицуСоСвойствамиCSV();

НоваяСтрока = СтруктураКолонок.Добавить();
НоваяСтрока.ИмяКолонки  = "Артикул";
НоваяСтрока.ТипЗначения = "Строка";
НоваяСтрока.Начало      = 0;
НоваяСтрока.Длина       = 3;

НоваяСтрока = СтруктураКолонок.Добавить();
НоваяСтрока.ИмяКолонки = "Наименование";
НоваяСтрока.ТипЗначения = "Строка";
НоваяСтрока.Начало      = 7;
НоваяСтрока.Длина       = 18;

НоваяСтрока = СтруктураКолонок.Добавить();
НоваяСтрока.ИмяКолонки = "ЕдиницаХранения";
НоваяСтрока.ТипЗначения = "Строка";
НоваяСтрока.Начало      = 25;
НоваяСтрока.Длина       = 2;

Пример чтения CSV-файла

Процедура ЗагрузитьCSV(ДвоичныеДанныеФайла, Расширение)

   // Либо аналогична примерам с Excel, либо свойства с началом и длиной
   СтруктураКолонок = ПолучитьСтруктуруЗагружаемогоОбъекта();
   
   // Помещаем файл во временное хранилище на сервере
   ПутьКФайлу = ПолучитьИмяВременногоФайла(Расширение);
	ДвоичныеДанныеФайла.Записать(ПутьКФайлу);

   // Если загрузка файла с разделителями, то 4-ым параметром указывается разделитель, например ";"
   // В противном случае не указывается
   // 3-им параметром указывается кодировка файла. По умолчанию "UTF8"
   СыраяТаблица = пбп_ЗагрузкаФайлаЧерезТабличныйДокументСервер
      .ПолучитьПромежуточнуюТаблицуИзCSVФайла(ПутьКФайлу, СтруктураКолонок);

   // Вызываем функцию конвертации строковых значений и передаем таблицу, полученную после чтения CSV-файла
   ТаблицаРезультат = пбп_ЗагрузкаФайлаЧерезТабличныйДокументСервер
      .ПреобразоватьСтроковыеЗначенияПоТипамСвойств(СыраяТаблица, СтруктураКолонок, Истина, "Y", , Ложь);
   
   // Для не найденных значений в итоговой таблице будут Null. Уберем их
   пбп_ЗагрузкаФайлаЧерезТабличныйДокументСервер.ТаблицаЗначенийБезNull(ТаблицаДанных);

   // Пост-обработка полученных данных
   // ...

КонецПроцедуры

Благодарность

Отдельная благодарность за идею реализации репозиторию Универсальная загрузка XLS с приведением типов