Сергей Пикин приводит пример работы с текстовым файлом при помощи класса 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