Импорт со структурой номенклатуры

Импорт со структурой номенклатуры

Сообщение serg525 » Сб сен 05, 2009 2:07 am

После экспорта номенклатуры в файле нет данных о структуре (может, конечно, я что-то не так делаю). Так вот хотелось бы иметь возможность импортировать со структурой сразу.
Я так понимаю, для этого достаточно всего двух полей:
FCOD, который описывает путь по дереву до элемента
FISGRP, чтобы отделять группы от самих товаров

Однако, если я имея такие поля в экселе начинаю импортировать такой файл в базу - выскакивает ошибка.
Я добавил две колонки в excel, в xml импорта добавляю соотвествующие строки:
<field length="0" link="" name="FCOD" newsource="false" objcod="" objsource="" param="C:\TechcomWork/IMPORT.xml" source="1">Путь к дереву</field>
<field length="0" link="" name="FISGRP" newsource="false" objcod="" objsource="" param="C:\TechcomWork/IMPORT.xml" source="2">Признак группы</field>

Что я делаю не так? Может есть другой путь для этого?

Еще вопрос, есть ли возможность добавлять пользовательские расширения номенклатуры при импорте, если их не было? Т.е. я импортирую файл, в котором есть мои дополнительные поля по товарам. В базе, допустим, к этому моменту их нет, создадутся ли соотвствующие поля? Желательно, конечно, чтобы текущие записи удалять не пришлось, а новое поле для них было пустым, допустим. Если никак, то хотя бы с полным очищением списка, это возможно?
Аватара пользователя
serg525
Начинающий
Начинающий
 
Сообщения: 8
Зарегистрирован: Ср авг 26, 2009 10:50 pm

Сообщение Evgeniy » Пн сен 07, 2009 10:16 am

Для импорта номенклатуры с группами достаточно одного поля FCOD. При этом код номенклатуры начинается с кода группы:
1. Фрукты (Группа)
1.1. Бананы
1.2. Апельсины
...
В Excel можно добавить строки для групп (если их нет) и проставить номера. После импорта выдается сообщение "Проставить группы для номенклатуры?" - жмем да. Значения полей FISGRP и FGRPID проставляются программой по коду, и таким макаром выстраивается иерархия дерева.
Чтобы редактировать настройку импорта не обязательно править xml, это можно сделать с помощью пользовательского меню.

Для импорта расширений нужно сначала создать их в базе. Если нужно импортировать расширения в существующие строки номенклатуры, можно настроить импорт на обновление. Для этого в настройке импорта нужно указать действие "Обновить", и настроить связку (например по коду).
Аватара пользователя
Evgeniy
Программист
 
Сообщения: 50
Зарегистрирован: Пн сен 03, 2007 1:50 pm
Откуда: Козирацкий Евгений

Сообщение serg525 » Ср сен 09, 2009 10:59 am

Допустим у меня большое количество excel файлов. В каждом из них часть полей общие, например, идентификационный код товара. А часть полей уникальны для каждого файла так как имею смысл только для данной группы товаров.
Поэтому, я хочу написать скрипт, скажем на Perl, который будет читать excel и подготваливать excel в необходимом формате и xml к нему, чтобы все было готов к импорту, ибо руками добавлять поле при импорте каждого файла просто нереально.
Поэтому необязательные поля должны иметь какое-то значение по-умолчанию, и если оно не указано в файле для импорта, то ставится значение по-умолчанию. А если появляется новое поле, то оно добавляется с необходимым значением, а ранее внесенные поля обзаводятся таким же полем со значением по умолчанию.
Еще, вопрос, есть ли возможность полу-автоматического экспорта? Или возможность выбрать сразу много xml файлов для импорта?

А теперь самый страшный вопрос...
Может описанное возможно только если я сам буду обновлять базу напрямую через подключение к SQL серверу? Сколько таблиц и в каком порядке мне необходимо тогда обновлять записи?
Аватара пользователя
serg525
Начинающий
Начинающий
 
Сообщения: 8
Зарегистрирован: Ср авг 26, 2009 10:50 pm

Сообщение serg525 » Ср сен 09, 2009 11:00 am

Еще вопрос по поводу дерева номенклатуры.
Как отделить в коде товары от папок?
Папки имеют точку в конце индекса последнего, а товары нет?

пару файлов для примера отправил на почту.
Аватара пользователя
serg525
Начинающий
Начинающий
 
Сообщения: 8
Зарегистрирован: Ср авг 26, 2009 10:50 pm

Сообщение Evgeniy » Ср сен 09, 2009 2:53 pm

serg525 писал(а):необязательные поля должны иметь какое-то значение по-умолчанию
В расширениях справочника можно указать значение по-умолчанию. Для основных полей можно проставить любое значение в настройке импорта даже если в Excel-файле нет таких значений, как это сделано для переменной FVID в настройке импорта номенклатуры: в поле источник вместо номера колонки указано конкретное значение ="S".

serg525 писал(а):есть ли возможность полу-автоматического экспорта? Или возможность выбрать сразу много xml файлов для импорта?
Есть возможность импортировать несколько Excel-файлов с помощью одной настройки, т.е. в одном xml-файле может содержатся несколько настроек для разных файлов-источников. Для этого в существующую настройку нужно добавить новые строки.

serg525 писал(а):Может описанное возможно только если я сам буду обновлять базу напрямую через подключение к SQL серверу?
При подключении к SQL серверу напрямую можете делать все что хотите . . .
Справочник номенклатуры храниться в таблице MTR_CL_NMK, расширения номенклатуры - в таблице CL_NMK. Основные поля для идентификации коменклатуры: FCOD - код номенклатуры и FWID - внутренний идентификатор (имеет уникальное значение).

serg525 писал(а):Как отделить в коде товары от папок? Папки имеют точку в конце индекса последнего, а товары нет?
Именно так.

serg525 писал(а):пару файлов для примера отправил на почту.
В настройке из списка переменных нужно удалить FISGRP.
Для переменных FTXT0, FFTXTS, FREM поставить тип "Текст".
После окончания импорта на вопрос "Проставить группы для номенклатуры" ответить Да.
Аватара пользователя
Evgeniy
Программист
 
Сообщения: 50
Зарегистрирован: Пн сен 03, 2007 1:50 pm
Откуда: Козирацкий Евгений

Сообщение serg525 » Ср сен 09, 2009 5:18 pm

Спасибо, импорт работает!

Еще один вопрос по импорту.

Каким образом можно настроить, что будет происходить при импорте - добавление/замещение информации?

Я пробую добавить/обновить информацию в БД. Для этого я добавляю в существующую импортируемую .xls - таблицу новые данные, а часть их изменяю. Пытаюсь снова импортировать ее с помощью xml-файла, указав параметр "добавить". При этом почему-то данные не изменяются, а добавляются, дублируя уже внесенные. Т.е. если импорт одной и той-же таблицы выполнить 5 раз, то товаров и папок в БД станет в 5 раз больше.
Аватара пользователя
serg525
Начинающий
Начинающий
 
Сообщения: 8
Зарегистрирован: Ср авг 26, 2009 10:50 pm

Сообщение Evgeniy » Ср сен 09, 2009 5:38 pm

"Добавить" и "Обновить" - два разных действия. Чтобы их выполнить нужно два разных файла-источника и две настройки.
Чтобы добавить новые данные нужно импортировать их из нового Excel-файла. Для обновления данных можно использовать старый файл.
Аватара пользователя
Evgeniy
Программист
 
Сообщения: 50
Зарегистрирован: Пн сен 03, 2007 1:50 pm
Откуда: Козирацкий Евгений

Импорт расширений

Сообщение serg525 » Чт сен 10, 2009 8:35 pm

Коротко обрисую ситуацию. Есть некий набор файлов, который я хочу импортировать в базу. Каждый файл содержит
данные по одному из типов товаров, где N полей общие для всех файлов (название, код, производитель и
несколько еще) и K уникальных для этой группы (например, рабочая температура, рабочая сила тока), которые в
другой группе товаров могут отсутствовать или быть частично другими.
Все поля, естественно, придется делать через расширения номенклатуры.
Задача импортировать данные в Debet Plus. Если с общими полями проблем может быть не столько много, их можно
добавить и руками, то уникальные поля для группы товаров вносить руками проблематично. Был придуман следующий алгоритм:
Обработать скриптом на перле все входные xsl файлы так, чтобы сформировать готовые к импорту так, чтобы все
впервые встречающиеся поля сразу вписывать в отдельный список расширений номенклатуры, который можно потом
перед импортом номенклатуры импортировать в систему с обновлением списка расширений. После чего система будет
готова к импорту любого из файлов, где упоминаются поля с расширениями.
Вроде все хорошо ложно быть, только вот способ импортировать расширения не нашлось. Как это можно сделать?
Есть ли какие-то промахи в нашем плане, которые могу встать на пути такого импорта товаров?

P.S. Правильно ли я понимаю, что поле в таблице номенклатуры получается из поля LABEL таблицы расширением
добавлением суффикса "X_F"?

-----------
С уважением,
Сергей
Аватара пользователя
serg525
Начинающий
Начинающий
 
Сообщения: 8
Зарегистрирован: Ср авг 26, 2009 10:50 pm

Сообщение Evgeniy » Пт сен 11, 2009 4:14 pm

serg525 писал(а):P.S. Правильно ли я понимаю, что поле в таблице номенклатуры получается из поля LABEL таблицы расширением
добавлением суффикса "X_F"?
Расширения номенклатуры хранятся в таблице CL_NMK. Связь с основной таблицей номенклатуры MTR_CL_NMK производиться через поле FMAINWID, т.е. CL_NMK.FMAINWID=MTR_CL_NMK.FWID. Названия полей в этой таблице образуются добавлением символа F к метке расширения. Суффикс X_ прибавляется в настройке импорта для распознавания расширений, чтобы не спутать их с основными переменными.

Что касается алгоритма, то есть способ добавления расширений программно. Для этого нужно написать небольшой скрипт. Чтобы этот скрипт выполнялся при запуске импорта нужно его поместить в папку, где лежит рабочий XML-файл с настройкой, и переименовать его в соответствии с этим XML-файлом.
Например если для импорта номенклатуры используется файл /base/org1/import/nmk.xml, будет выполнятся скрипт /base/org1/import/nmk.js.
В скрипте для импорта номенклатуры должна быть описана функция importTbl.
Для создания расширений используется объект DpExtentionBuilder ("Objects/DpExtentionBuilder.js").
В принципе ничего сложного. . .
Рассмотрим на примере как работает функция импорта при добавлении новых строк.

function importTbl(sTblName, tblSource, oImporter)
{
//sTblName- название таблицы-приемника (для номенклатуры MTR_CL_NMK);
//tblSource – таблица с импортируемыми строками;
//oImporter – объект DbImporter (JDebet/scripts/Objects/DbImporter.js)

//цикл прохождения по импортируемым строкам
for(; !tblSource.isEOF(); tblSource.MoveNext())
{
var sFld = ""; //поля для вставки в таблицу-приемник
var sVal = ""; //значения переменных
var fcod = ""; //код номенклатуры
var fwid = 0; //идентификатор
var groupCod = ""; //код группы, можно поставить "0001." или другой
var arrExt = new Array(); //массив расширений

//проходим по всем переменным из настройки импорта
for(sFldTo in oImporter.varMap)
{
var fld = oImporter.varMap[sFldTo]; //название поля таблицы с импортируемыми строками
if(!fld || !sFldTo)
continue;

var sType = oImporter.getVarType(sFldTo); //тип переменной
var oVal = oImporter.getValue(fld, tblSource, sType, sFldTo); //значение переменной из источника
if(oVal==null || oVal=="undefined")
continue;

//делаем проверку является ли переменная расширением
//название расширения начинается с X_
if(oImporter.isExt(sFldTo))
{
arrExt[sFldTo] = oVal; //пока заносим значение расширения в массив
continue;
}

//создаем объекты, например для единиц измерения
if(oImporter.isObject(sType))
oVal = oImporter.createObject(sType, oVal, sFldTo);

if(sFldTo=="FCOD")
{
if(groupCod)
oVal = groupCod + oVal;
fcod = oVal;
}

//собираем все поля и значения в одну строку для SQL-запроса
sFld += sFldTo +",";
sVal += sqlTo(oVal) +",";
}

//добавляем идентификатор
fwid = GetUID();
sFld += "FWID";
sVal += fwid;

//для номенклатуры предусмотрен ряд обязательных полей
if(sTblName.indexOf("MTR_CL_NMK")!=-1)
{
if(sFld.toUpperCase().indexOf("FCOD")==-1)
{
sFld += ",FCOD";
sVal += ","+ sqlTo(nextNmkCod(groupCod));
}
if(sFld.toUpperCase().indexOf("FCEDIB")==-1)
{
sFld += ",FCEDIB";
sVal += ","+ sqlTo(1);
}
if(sFld.toUpperCase().indexOf("FEDI_SPR")==-1)
{
sFld += ",FEDI_SPR";
sVal += ","+ sqlTo(1);
}
if(sFld.toUpperCase().indexOf("FEDI1")==-1)
{
sFld += ",FEDI1";
sVal += ","+ sqlTo(1);
}
if(sFld.toUpperCase().indexOf("FFAS1")==-1)
{
sFld += ",FFAS1";
sVal += ","+ sqlTo(0);
sFld += ",FFAS2";
sVal += ","+ sqlTo(0);
sFld += ",FFAS3";
sVal += ","+ sqlTo(0);
sFld += ",FFAS4";
sVal += ","+ sqlTo(0);
sFld += ",FFAS5";
sVal += ","+ sqlTo(0);
}
if(sFld.toUpperCase().indexOf("FGRPID")==-1)
{
sFld += ",FGRPID";
sVal += ","+ createNmkGroup(groupCod);
sFld += ",FISGRP";
sVal += ","+ sqlTo(false);
}

if(!oImporter.checkCod(fcod, 0, "nmk"))
return false;
}

//формируем SQL-запрос для добавления импортируемой строки
var sSql = "insert into "+ sTblName +" ("+ sFld +") values ("+ sVal +")";
var bRet = ExecuteSQL(sSql);
if(!bRet && stopMassage(sTblName))
return;

var sTbl = sTblName;
if(sTblName.indexOf(".")!=-1)
sTbl = sTblName.substring(sTblName.indexOf(".")+1);

//добавляем недостающие расширения
if(sTblName.indexOf("MTR_CL_NMK")!=-1)
{
for(sVar in arrExt)
{
if(arrExt[sVar]==null)
continue;
var sLabel = sVar.substring(3);
addNmkExt(sLabel, sType, null);
}
}
//сохраняем значения расширений
oImporter.saveExt(sTbl, arrExt, fwid);
}

if(sTblName.indexOf("MTR_CL_NMK")!=-1)
{
//выстраиваем дерево номенклатуры
buildNmkGroups(true);
}
}

//функция для добавления расширений номенклатуры
function addNmkExt(sLabel, sType, sTxt)
{
include("Objects/DpExtentionBuilder.js");

sLabel = sLabel.toUpperCase().trim();
var oSnap = getSnap("select FWID, FTXT from ^CL_EXT where UPPER(FCLASS)='CL_NMK' and UPPER(FLABEL)="+ sqlTo(sLabel));
if(oSnap && oSnap[0])
return;

var num = 1;
oSnap = getSnap("select max(FPOS) from ^CL_EXT where UPPER(FCLASS)='CL_NMK'");
if(oSnap && oSnap[0])
num = Number(oSnap[0])+1;

var extBuilder = new DpExtentionBuilder("CL_NMK");
extBuilder.load();

var mCl = new Object();
mCl.FWID = GetUID();
mCl.Flabel = sLabel;
if(sTxt)
mCl.Ftxt = sTxt;
else
mCl.Ftxt = sLabel;
mCl.Fcomment = sTxt;
mCl.Fwidth = 10;
mCl.Fpos = num;
mCl.Fused = true;
mCl.FISCHECK = false;
mCl.Ftype = extType(sType);
mCl.Fformat = "";
mCl.Fisculc = false;
mCl.FCLASS = extBuilder.FCLASS;
if (extBuilder.FSUBCLASS)
mCl.FSUBCLASS = extBuilder.FSUBCLASS;
UpdateTable(extBuilder.getInfoTableName(), mCl, true);

extBuilder.commitStructure();
mCl.Fdefault = "";
extBuilder.save(mCl);
}

function extType(sType)
{
sType = String(sType).toLowerCase();
if(sType.indexOf("text")!=-1)
return "TEXT";
switch(sType)
{
case "bit":
case "5":
return "BOOL";
case "double":
case "4":
return "FLOAT";
case "long":
case "2":
return "INT";
case "1":
return "TEXT";
}
return sType.toUpperCase();
}

Такой скрипт создаст в базе недостающие расширения, которые описаны в настройке импорта.
Аватара пользователя
Evgeniy
Программист
 
Сообщения: 50
Зарегистрирован: Пн сен 03, 2007 1:50 pm
Откуда: Козирацкий Евгений

Сообщение Dragon31337 » Сб сен 19, 2009 9:01 pm

А как в объекте получить занчение камента из XML. Не поле To, а что сто в самом теге для каждого импортируемого элемента.
Так это нечно комента что-то и нигде не используется, я хочу записывать туда описание расширения и при экспорте брать его отуда.
Аватара пользователя
Dragon31337
Начинающий
Начинающий
 
Сообщения: 6
Зарегистрирован: Чт авг 27, 2009 7:42 pm

Сообщение Evgeniy » Пн сен 21, 2009 12:05 pm

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

sFld ="X_FNDS"; //имя переменной
var sTxt = "";
var oSnap = getSnap("select FTXT from "+ oImporter.varsTblName +" where UPPER(FREC)="+ sqlTo(sFld.toUpperCase()));
if(oSnap)
sTxt = oSnap[0];
Аватара пользователя
Evgeniy
Программист
 
Сообщения: 50
Зарегистрирован: Пн сен 03, 2007 1:50 pm
Откуда: Козирацкий Евгений

Сообщение Dragon31337 » Пн сен 21, 2009 10:30 pm

Это точно так? У меня всегда возвращается один и тот же текст. дейситвельно комментарий, но от одного и того же тега....
Может, я конечно что-то не так делаю, перепробовал уже много чего
мои изменения:

if(oImporter.isExt(sFldTo))
{
arrExt[sFldTo] = oVal; //пока заносим значение расширения в массив
var oSnap = getSnap("select FTXT from "+ oImporter.varsTblName +" where UPPER(FREC)="+ sqlTo(sFldTo.toUpperCase()));
if(oSnap)
arrCom[sFldTo] = oSnap[0];

continue;
}


Массив, конечно объявил

//добавляем недостающие расширения
if(sTblName.indexOf("MTR_CL_NMK")!=-1)
{
for(sVar in arrExt)
{
if(arrExt[sVar]==null)
continue;
var sLabel = sVar.substring(3);
addNmkExt(sLabel, sType, arrCom[sVar] );
}
}
//сохраняем значения расширений
oImporter.saveExt(sTbl, arrExt, fwid);
}



Правда,почему тут используется sType - не совсем понятно, ибо в нем на сколько я понимаю тип последнего элемента из всех в списке импортируемых, и мало того, что он может быть другого типа, так и сраширения могут быть разного.
Я может код как-то не так читаю... Но я программировал на си, Java близок.
Да, есть какой-то режим отладки, чтобы скрипты проверять?
Аватара пользователя
Dragon31337
Начинающий
Начинающий
 
Сообщения: 6
Зарегистрирован: Чт авг 27, 2009 7:42 pm

Сообщение Evgeniy » Вт сен 22, 2009 9:54 am

Можно написать так

//добавляем недостающие расширения
if(sTblName.indexOf("MTR_CL_NMK")!=-1)
{
for(sVar in arrExt)
{
if(arrExt[sVar]==null)
continue;
var sLabel = sVar.substring(3);
var sType = oImporter.getVarType(sVar);
var sTxt = "";
var oSnap = getSnap("select FTXT from "+ oImporter.varsTblName +" where UPPER(FREC)="+ sqlTo(sVar.toUpperCase()));
if(oSnap)
sTxt = oSnap[0];

addNmkExt(sLabel, sType, sTxt);
}
}
Аватара пользователя
Evgeniy
Программист
 
Сообщения: 50
Зарегистрирован: Пн сен 03, 2007 1:50 pm
Откуда: Козирацкий Евгений

Сообщение Dragon31337 » Вт сен 22, 2009 2:47 pm

Я нечто похожее и написал с самого начала, но у меня это не сработало тогда. Сейчас, вроде, работает. Спасибо.
Аватара пользователя
Dragon31337
Начинающий
Начинающий
 
Сообщения: 6
Зарегистрирован: Чт авг 27, 2009 7:42 pm

Сообщение Dragon31337 » Чт сен 24, 2009 12:25 am

Можно как-то указать в этом скритпе тот факт, что мне надо пропусить первую строчку в импортируемом XLS?
А то не хочется пересоздавать все файлы только для того, чтобы убрать заголовок таблицы.
Аватара пользователя
Dragon31337
Начинающий
Начинающий
 
Сообщения: 6
Зарегистрирован: Чт авг 27, 2009 7:42 pm

След.

Вернуться в Общие вопросы по работе программы

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 7