Сергей Пикин приводит пример работы с текстовым файлом при помощи класса CommaIO.

С базовой информацией о классах Axapta, предназначенных для работы с текстовыми файлами, можно ознакомиться тут. В данном примере рассматривается импорт данных в справочник номенклатуры из текстового файла с разделителями.

Структура файла:

Номенклатура1~Вес номенклатуры
Номенклатура2~Вес номенклатуры
Номенклатура3~Вес номенклатуры 

Пример:

{
   #define.FieldsCol(2)
   #define.Delimiter("~") 
   #define.strFileName("c:\\ test.txt")

   CommaIO     inventoryCommaIO; 
   Container   c; 
   InventTable inventTable; 
   str         strItemId, strWeight; 
   int         lineNum;
 
   inventoryCommaIO = new CommaIO(#strFileName, "R");
   if ( !inventoryCommaIO)
      throw error( strfmt("Файл %1 не открывается", #strFileName ));

   inventoryCommaIO.inFieldDelimiter(#Delimiter);
 
   ttsbegin;
   while(inventoryCommaIO.status()==IO_Status::OK)
   {
      if( inventoryCommaIO.status() ) 
         throw error("@SYS52680");
 
      c = inventoryCommaIO.read(); 
      lineNum++;
 
      if( conlen(c) != #FieldsCol )
      { 
          warning(strfmt("Нарушен формат строки #%1", lineNum));
          continue;
      } 

      strItemId = strLRtrim(conpeek(c, 1)); 
      strWeight = conpeek(c, 2);
 
      inventTable = InventTable::find(strItemId, true); 
      if( inventTable.RecId == 0 )
      {
         warning(strfmt("Не найдена номенклатура %1", strItemId));
         contunie;
      }
      inventTable.NetWeight = str2num(strWeight); 
      inventTable.update(); 
   }
   ttscommit;
   info ( strfmt ("Данные из файла %1 импортированы", #strFileName )); 
} 

Основные свойства и методы, использованные в примере:

Метод, свойство

Описание

inventoryCommaIO = new CommaIO(#strFileName, "R");

Создание нового экземпляра класса CommaIO.

Параметры: имя файла, режим работы с файлом ("R" - чтение, "W" - запись, "A" – режим добавления (записи))

inventoryCommaIO.status()

Возвращает статус последней операции, выполненной с файлом (возвращаемое значение представлено перечислимым типом IO_Status)

inventoryCommaIO.inFieldDelimiter(#Delimiter)

Установка разделителя полей в файле (по умолчанию - запятая). Дополнительно могут использоваться свойства inRecordDelimiter – разделитель записей и inRecordLength – количество символов в записи

inventoryCommaIO.read()

Считывает порцию данных из файла в соответствии с установленными свойствами inFieldDelimiter , inRecordDelimiter и inRecordLength и смещает указатель текущей позиции в файле.

Возвращает переменную типа контейнер, содержащую считанные данные.

В приведенном примере не использовалось свойство inRecordDelimiter, т.к. структура импортируемого файла достаточно проста (каждая строка в файле соответствует одной записи). Однако при разборе текстовых файлов более сложной структуры его использование может принести большую пользу. Пример подобного разбора приведен на axforum.ru.

Структура файла:

Поле 1 = 111
Поле 2 = 444
Поле 3 = 555
Кон
Поле 1 = 888
Поле 2 = 777
Поле 3 = 999
Кон 

Пример:

{
   #define.FileName("c:\\test.txt")
CommaIO file;
container line;
int recNum;
str linePart;
file = new CommaIO(#FileName, "R"); if (file) { if (file.status()) throw error("@SYS52680");
file.inFieldDelimiter("\r\n");
file.inRecordDelimiter("Кон\r\n"); setPrefix(#FileName); recNum = 0; while (file.status() == IO_Status::Ok) { line = file.read(); if (conlen(line)) { recNum ++; setprefix("Record " + int2str(recNum)); for (linePart = ""; conlen(line); line = condel(line, 1, 1)) {
linePart = conpeek(line, 1);
info(linePart);
}
}
}
} }

Сергей Пикин, pikin@rabota-na-rezultat.ru