Функция обратная WHERE()

Clarion, Clarion 7

Модератор: Дед Пахом

Правила форума
При написании вопроса или обсуждении проблемы, не забывайте указывать версию Clarion который Вы используете.
А так же пользуйтесь спец. тегами при вставке исходников!!!
Аватара пользователя
finsoftrz
✯ Ветеран ✯
Сообщения: 4615
Зарегистрирован: 06 Ноябрь 2014, 12:48
Благодарил (а): 6 раз
Поблагодарили: 37 раз

Функция обратная WHERE()

Сообщение finsoftrz »

Кстати, насчет боязни временных файлов. Вспомнил про xlsx, который не так давно мучили. Там кучка файлов в куче подкаталогов, завернутые в zip архив. Скорее всего, при работе все это распаковывается во временные каталоги и файлы. Это в "современном" формате, а старый xls это один файл. Несправедливо. :-)
C6/C11, ШВС, tps/btrieve.
Аватара пользователя
Игорь Столяров
Ветеран движения
Сообщения: 7374
Зарегистрирован: 07 Июль 2005, 10:19
Откуда: г. Ростов-на-ДоМу
Благодарил (а): 13 раз
Поблагодарили: 48 раз

Функция обратная WHERE()

Сообщение Игорь Столяров »

finsoftrz писал(а): 27 Февраль 2023, 13:15 Если есть вложенные теги, то в name они указываются через "/"
Да, всё верно. Но есть небольшой нюанс. Если предположим, есть группа тегов с данными ФЛ
(Имя, Фамилия, Отчество) и она встречается в структуре с 8-9 уровнями вложенности раз 20 -
то будет очень грустно прописывать к каждому тегу "Имя" полный путь. Хотя конечно и возможно.

Но если мы хотим получить общее решение, которое будет работать всегда и везде - то нужно
брать структуру данных ФНС и парсить по ней. Как бы грустно это не было ...
За теми кто отстал - не возвращаться. (С) Кодекс
Аватара пользователя
finsoftrz
✯ Ветеран ✯
Сообщения: 4615
Зарегистрирован: 06 Ноябрь 2014, 12:48
Благодарил (а): 6 раз
Поблагодарили: 37 раз

Функция обратная WHERE()

Сообщение finsoftrz »

Про 20 раз 8-9 уровней - это, наверно, образно? :-)
Смысл в том, что "парсер" один, соответствие прописывается в структуре данных, а не в вызовах методов.
Длинные имена тэгов встречаются, например, в ветисе. Длиннее пока не попадалось.

Код: Выделить всё

lor:queueZag queue,pre()
lor:date  string(20), name('vd:issueDate')
lor:dateLong  string(40), name('vd:lastUpdateDate')
lor:uuid  string(40), name('bs:uuid')
lor:form  string(10), name('vd:vetDForm')
lor:type  string(20), name('vd:vetDType')
lor:stat  string(20), name('vd:vetDStatus')
lor:perishable string(20), name('vd:certifiedConsignment/vd:batch/vd:perishable')
lor:sendHS   string(40), name('vd:certifiedConsignment/vd:consignor/dt:businessEntity/bs:guid')
lor:sendEnt  string(40), name('vd:certifiedConsignment/vd:consignor/dt:enterprise/bs:guid')
lor:reciveHS string(40), name('vd:certifiedConsignment/vd:consignee/dt:businessEntity/bs:guid')
lor:reciveEnt  string(40), name('vd:certifiedConsignment/vd:consignee/dt:enterprise/bs:guid')
lor:prodType   string(10), name('vd:certifiedConsignment/vd:batch/vd:productType')
lor:prodGUID   string(40), name('vd:certifiedConsignment/vd:batch/vd:product/bs:guid')
lor:prodSubGUID string(40), name('vd:certifiedConsignment/vd:batch/vd:subProduct/bs:guid')
lor:prodItGUID string(40), name('vd:certifiedConsignment/vd:batch/vd:productItem/bs:guid')
lor:prodName   string(255),name('vd:certifiedConsignment/vd:batch/vd:productItem/dt:name')
lor:value      string(20), name('vd:certifiedConsignment/vd:batch/vd:volume')
lor:firstYear  string(10), name('vd:certifiedConsignment/vd:batch/vd:dateOfProduction/vd:firstDate/dt:year')
lor:firstMonth string(10), name('vd:certifiedConsignment/vd:batch/vd:dateOfProduction/vd:firstDate/dt:month')
lor:firstDay   string(10), name('vd:certifiedConsignment/vd:batch/vd:dateOfProduction/vd:firstDate/dt:day')
lor:firsthour  string(10), name('vd:certifiedConsignment/vd:batch/vd:dateOfProduction/vd:firstDate/dt:hour')
lor:endYear    string(10), name('vd:certifiedConsignment/vd:batch/vd:expiryDate/vd:firstDate/dt:year')
lor:endMonth   string(10), name('vd:certifiedConsignment/vd:batch/vd:expiryDate/vd:firstDate/dt:month')
lor:endDay     string(10), name('vd:certifiedConsignment/vd:batch/vd:expiryDate/vd:firstDate/dt:day')
lor:endhour    string(10), name('vd:certifiedConsignment/vd:batch/vd:expiryDate/vd:firstDate/dt:hour')
lor:unit       string(40), name('vd:certifiedConsignment/vd:batch/vd:unit/bs:guid')
lor:country    string(40), name('vd:certifiedConsignment/vd:batch/vd:origin/vd:country/bs:guid')
lor:packingLevel string(10), name('vd:certifiedConsignment/vd:batch/vd:packageList/dt:package/dt:level')
lor:packingType  string(40), name('vd:certifiedConsignment/vd:batch/vd:packageList/dt:package/dt:packingType/bs:guid')
lor:packingID    string(20), name('vd:certifiedConsignment/vd:batch/vd:packageList/dt:package/dt:packingType/dt:globalID')
lor:packingKol   string(10), name('vd:certifiedConsignment/vd:batch/vd:packageList/dt:package/dt:quantity')
lor:transpType   string(10), name('vd:certifiedConsignment/vd:transportInfo/vd:transportType')
lor:transpCont   string(40), name('vd:certifiedConsignment/vd:transportInfo/vd:transportNumber/vd:containerNumber')
lor:transpTrail  string(40), name('vd:certifiedConsignment/vd:transportInfo/vd:transportNumber/vd:trailerNumber')
lor:transpNumber  string(60), name('vd:certifiedConsignment/vd:transportInfo/vd:transportNumber/vd:vehicleNumber')
lor:transpStorage string(20), name('vd:certifiedConsignment/vd:transportStorageType')
lor:transpType2   string(10), name('vd:nextTransport/vd:transportType')
lor:transpCont2   string(40), name('vd:nextTransport/vd:transportNumber/vd:containerNumber')
lor:transpTrail2  string(40), name('vd:nextTransport/vd:transportNumber/vd:trailerNumber')
lor:transpNumber2 string(40), name('vd:nextTransport/vd:transportNumber/vd:vehicleNumber')
lor:brokerGUID    string(40), name('vd:certifiedConsignment/vd:broker/bs:guid')
lor:authPurpose   string(40), name('vd:authentication/vd:purpose/bs:guid')
lor:authInsp      string(20), name('vd:authentication/vd:cargoInspected')
lor:authExp       string(20), name('vd:authentication/vd:cargoExpertized')
lor:authLoc       string(128), name('vd:authentication/vd:locationProsperity')
.
То есть подход простой. То, что можно формализовать и получать одним методом, формализуем и используем для всех разновидностей xml, используя соответствие названий тэгов и name у полей в кларионовских структурах. Для сложных случаев, когда удумаешься формализовывать, тупо встраивается код на vbscript, который сам по себе достаточно простой, понятный и гуглодоступный. В кьюшках/группах в этом случае name можно задать как угодно (только согласовано с кодом vbscript).
C6/C11, ШВС, tps/btrieve.
Аватара пользователя
Игорь Столяров
Ветеран движения
Сообщения: 7374
Зарегистрирован: 07 Июль 2005, 10:19
Откуда: г. Ростов-на-ДоМу
Благодарил (а): 13 раз
Поблагодарили: 48 раз

Функция обратная WHERE()

Сообщение Игорь Столяров »

finsoftrz писал(а): 27 Февраль 2023, 14:27 Про 20 раз 8-9 уровней - это, наверно, образно?
К сожалению, нет. Это про структуру документа ЭДО. Только полную.
Например, фамилия поставщика ИП: Loc:MyFile.Document.SvSchFact.SvPokup.IdSv.SvIP.FIO.Fam
finsoftrz писал(а): 27 Февраль 2023, 14:27 lor:firstYear string(10), name('vd:certifiedConsignment/vd:batch/vd:dateOfProduction/vd:firstDate/dt:year')
lor:firstMonth string(10), name('vd:certifiedConsignment/vd:batch/vd:dateOfProduction/vd:firstDate/dt:month')
lor:firstDay string(10), name('vd:certifiedConsignment/vd:batch/vd:dateOfProduction/vd:firstDate/dt:day')
lor:firsthour string(10), name('vd:certifiedConsignment/vd:batch/vd:dateOfProduction/vd:firstDate/dt:hour')
....
lor:endYear string(10), name('vd:certifiedConsignment/vd:batch/vd:expiryDate/vd:firstDate/dt:year')
lor:endMonth string(10), name('vd:certifiedConsignment/vd:batch/vd:expiryDate/vd:firstDate/dt:month')
lor:endDay string(10), name('vd:certifiedConsignment/vd:batch/vd:expiryDate/vd:firstDate/dt:day')
lor:endhour string(10), name('vd:certifiedConsignment/vd:batch/vd:expiryDate/vd:firstDate/dt:hour')
Тот же самый [ПИП] и у нас в Меркурии. Работает. И переделывать это конечно уже никто не будет. :(
Но смотрите, в этой цитате заданы теги типовой даты производства и срока годности (неполные).
И каждая такая типовая дата каждый раз разворачивается в полный путь ... хотя должна быть описана один раз.
И так везде. Вместо структуры - кирпичи, с которыми сложно работать, модифицировать и т.д.

Конечно же в новых проектах такое лепить уже не хочется.
За теми кто отстал - не возвращаться. (С) Кодекс
Аватара пользователя
finsoftrz
✯ Ветеран ✯
Сообщения: 4615
Зарегистрирован: 06 Ноябрь 2014, 12:48
Благодарил (а): 6 раз
Поблагодарили: 37 раз

Функция обратная WHERE()

Сообщение finsoftrz »

А какие варианты, циклы с флагами и case/if? На мое восприятие, это еще хуже.
C6/C11, ШВС, tps/btrieve.
Аватара пользователя
finsoftrz
✯ Ветеран ✯
Сообщения: 4615
Зарегистрирован: 06 Ноябрь 2014, 12:48
Благодарил (а): 6 раз
Поблагодарили: 37 раз

Функция обратная WHERE()

Сообщение finsoftrz »

В принципе, никто нам не мешает оформить повторяющиеся названия тэгов в виде макросов. Как-то не думалось в эту сторону. Вроде все понятно, как есть в структуре, так и пишем в name.
C6/C11, ШВС, tps/btrieve.
Аватара пользователя
Игорь Столяров
Ветеран движения
Сообщения: 7374
Зарегистрирован: 07 Июль 2005, 10:19
Откуда: г. Ростов-на-ДоМу
Благодарил (а): 13 раз
Поблагодарили: 48 раз

Функция обратная WHERE()

Сообщение Игорь Столяров »

finsoftrz писал(а): 27 Февраль 2023, 15:16 На мое восприятие, это еще хуже
Здесь нужно понять главное различие подходов.
XML (JSON) - это структурированные данные. Не CSV / TXT.
Нахождение данных на определённом уровне структуры - задаёт и меняет смысл этих данных.

При работе с "длинными" именами - мы в линейном GROUP и пытаемся описать структуру в Name('X1\X2\X3 ...')
Но ведь можно (и правильно !) задать эту структру через вложенные GROUP.
И тогда не нужно повторять развёрнутым каждый типовой тег только для того, что бы задать его NAME. Вот ! :)
За теми кто отстал - не возвращаться. (С) Кодекс
Аватара пользователя
finsoftrz
✯ Ветеран ✯
Сообщения: 4615
Зарегистрирован: 06 Ноябрь 2014, 12:48
Благодарил (а): 6 раз
Поблагодарили: 37 раз

Функция обратная WHERE()

Сообщение finsoftrz »

Мне кажется, это дебри. То есть, по сути, Вы пытаетесь на кларионовских структурах сделать зеркальное отражение xml. База данных у нас не древовидная, а реляционная. Смысл парсинга не повторить все внешние структуры, а привести получаемую из них информацию к стандартному для нас представлению, с которым мы работаем внутри приложения. То есть к набору обычных кьюшек и групп. Потом надо с этой информацией работать - сохранять в базе данных, выводить в окна или печатные формы. Я это так воспринимаю.
C6/C11, ШВС, tps/btrieve.
Аватара пользователя
Игорь Столяров
Ветеран движения
Сообщения: 7374
Зарегистрирован: 07 Июль 2005, 10:19
Откуда: г. Ростов-на-ДоМу
Благодарил (а): 13 раз
Поблагодарили: 48 раз

Функция обратная WHERE()

Сообщение Игорь Столяров »

finsoftrz писал(а): 27 Февраль 2023, 17:34 на кларионовских структурах сделать зеркальное отражение xml
Иное. Я пытаюсь работать с той же структурой данных, в которой составлен XML документ.
Т.е. у документа есть покупатель, покупатель имеет данные ЮЛ, у ЮЛ есть директор, у директора есть ФИО.
Эта структура - свойство данных. А Вы переводите это в свойство кода - задавая в Name('X1\X2 ...') параметры (программу)
работы парсера / скрипта для поиска данных. Ну и для себя название поля - что совсем в этом не запутаться.

Но сама Queue - линейна, все поля равноправны и ещё придётся выкручиваться с именами, если несколько раз
встречаются однотипные структуры вроде даты или ФИО ...

По Вашему примеру из Меркурия - Вы не можете просто одной командой удалить срок годности или присвить ей
дату производства. Или добавить во все места где встречается дата - неформальное значение informalDate.
Поиск, перебор полей, что-то потерялось, где-то съехало и т.д. :(
За теми кто отстал - не возвращаться. (С) Кодекс
Аватара пользователя
finsoftrz
✯ Ветеран ✯
Сообщения: 4615
Зарегистрирован: 06 Ноябрь 2014, 12:48
Благодарил (а): 6 раз
Поблагодарили: 37 раз

Функция обратная WHERE()

Сообщение finsoftrz »

Зачем надо "одной командой удалить срок годности или присвоить ей дату производства"? Что-то Вы заработались. :dizzy:
На мое восприятие, куда проще - создали структуру/структуры, в которой заложено то, что нам надо в терминах предметной области. Приписали name, которое соответствует тэгам в xml. Размазано у них по нескольким тэгам (как дата на год, месяц, день), подстроились, после парсинга приведем к обычной дате, в таком виде оно использоваться дальше не будет. Я не очень понимаю, зачем из одной сложной иерархической структуры грузить в другую сложную иерархическую структуру. Чтобы потом что?

К слову, загружать ФИО из накладной в ЭДО идея фикс. Информация о контрагенте заносится в информационную систему при заключении договора, а не когда шлют накладные. Из файла ЭДО достаточно взять ИНН, по нему определяется контрагент.
C6/C11, ШВС, tps/btrieve.
Аватара пользователя
Игорь Столяров
Ветеран движения
Сообщения: 7374
Зарегистрирован: 07 Июль 2005, 10:19
Откуда: г. Ростов-на-ДоМу
Благодарил (а): 13 раз
Поблагодарили: 48 раз

Функция обратная WHERE()

Сообщение Игорь Столяров »

finsoftrz писал(а): 27 Февраль 2023, 18:35 в информационную систему при заключении договора, а не когда шлют накладные
Бывает и такое. :) Но ведь не обязательно для покупки товара заключать договор ...
Вы пытаетесь вместо решения общей задачи загрузки данных из ЭДО (или любой XML) -
каждый раз решать задачу конкретного бухгалтера с его идеями. Пришёл документ,
где торкнуло записать штрих-код в GTIN - делаем так, потом пришёл документ где
штрих-код в поле кода, добавили в скрипт костыль искать штрих-код там ...

И вроде, всё работает сразу в двух местах. Но это тупиковый путь - Вы рано или поздно
столкнётесь с объёмами данных, которые сложно лечить костылями "по факту обращения".
А попытка сделать парс XML правильно приведёт Вас туда же, куда и меня. ;)
За теми кто отстал - не возвращаться. (С) Кодекс
Аватара пользователя
finsoftrz
✯ Ветеран ✯
Сообщения: 4615
Зарегистрирован: 06 Ноябрь 2014, 12:48
Благодарил (а): 6 раз
Поблагодарили: 37 раз

Функция обратная WHERE()

Сообщение finsoftrz »

Откуда Вы знаете, как правильно? Любое решение принимается во времени, на основании тех знаний, которые есть на этот момент. Есть интуиция и опыт, которые позволяют выстраивать систему таким образом, чтобы минимизировать затраты на внесение изменений, когда исходные вводные поменяются.
В примере со штрих-кодом. Реальные случаи из практики, когда один поставщик при наличии gtin (для маркированных товаров) не указывает штрих-код в дополнительных параметрах товара. А для немаркированных товаров указывает. Пока не придет подобная накладная, об этом и не узнаете.
Вообще, это банальные вещи, странно, что приходится рассказывать. Погуглите про agile и подобные современные методики разработки.
Про тупиковый путь и костыли, это было смешно.
C6/C11, ШВС, tps/btrieve.
Аватара пользователя
Игорь Столяров
Ветеран движения
Сообщения: 7374
Зарегистрирован: 07 Июль 2005, 10:19
Откуда: г. Ростов-на-ДоМу
Благодарил (а): 13 раз
Поблагодарили: 48 раз

Функция обратная WHERE()

Сообщение Игорь Столяров »

finsoftrz писал(а): 27 Февраль 2023, 20:31 Откуда Вы знаете, как правильно?
Инструкцию прочитал. :) Я понимаю, что обидно когда кто-то приходит и обесценивает
казалось бы огромный труд "тонкой настройки по реальной практике". Но я с уважением
отношусь к любой работе и ищу пути решения общей задачи по законодательству РФ. ;)
За теми кто отстал - не возвращаться. (С) Кодекс
Аватара пользователя
finsoftrz
✯ Ветеран ✯
Сообщения: 4615
Зарегистрирован: 06 Ноябрь 2014, 12:48
Благодарил (а): 6 раз
Поблагодарили: 37 раз

Функция обратная WHERE()

Сообщение finsoftrz »

Обижаются дети в песочнице. :-)
Вы ничего не обесценили, все давно сделано и успешно работает в изменяющихся условиях. Затраты минимальны, я же не пытаюсь объять необъятное. Игорь, Вы меня так троллите или реально думаете, что достаточно "прочитать инструкцию" и со всеми нюансами разберетесь? Думаю, все таки первое, так как сами понимаете, что инструкции очень объемные, содержат много избыточной информации о том, что у Ваших пользователей никогда не встретится, в них много противоречий и нестыковок, много чего не оговорено, они еще и регулярно изменяются. Одному человеку не под силу разбираться во всем этом, да еще автоматизировать. Поэтому я стараюсь максимально включать пользователей. Совместно читаем, обсуждаем, они по своим каналам консультируются, смотрим реализации где-нибудь в 1с, сбис и т.п., потом картинка устаканивается, делается реализация в системе, потом совместно тестируем на реальных данных. Вариантов нет, иначе не работает, слишком много ресурсов надо.
C6/C11, ШВС, tps/btrieve.
Аватара пользователя
Игорь Столяров
Ветеран движения
Сообщения: 7374
Зарегистрирован: 07 Июль 2005, 10:19
Откуда: г. Ростов-на-ДоМу
Благодарил (а): 13 раз
Поблагодарили: 48 раз

Функция обратная WHERE()

Сообщение Игорь Столяров »

Я инструкцией называю законодательство РФ. Там всё конкретно (хотя и нудно) описано.
Если сравнивать с Меркурием - то объём документации по ЭДО просто смешной. :)

Я хочу иметь инструмент, который позволит разбирать документ ЭДО (и любой XML файл)
в соответствии с законодательством РФ. И это не исключает т.н. тонких местных настроек.

К моему большому сожалению Вы не можете посмотреть пример парсера на улучшенной
среде разработки. А там показано, как получается список дополнительных показателей
в структуру "ТекстИнфТип" (самого бесит - но так её назвали в законе).

И если какой-то местный укротитель 1С туда пишет штрих-коды - заберите их там.
Завтра захочет записать срок годности или сертификат - заберите, без проблем.

И для этого не нужно каждый раз "улучшать" и настраивать парсер, потому что в законе
предусмотрена запись в эту структуру дополнительной информации о товаре.
Нужно просто один раз сделать получение всех данных и далее их использовать.
Как-то так. :)
За теми кто отстал - не возвращаться. (С) Кодекс
Ответить