13.09.2010, 15:58 | #21 |
Administrator
|
Цитата:
По поводу констант - от их использования никуда не убежишь. И их использование заменяется использованием макросов. Если бы можно было бы от констант отказаться - то давно б отказались. Не приветствуется использование таких констант, которые не могут быть константами - ставка налога к примеру. А какие-то вещи - типа количество дней в году, или "волшебный номер" 255 - вполне может использоваться. Как раз-таки его и не потребовалось бы использовать - если бы все енумы начинались бы с нулевого ничего не значащего значения.
__________________
Возможно сделать все. Вопрос времени |
|
13.09.2010, 16:04 | #22 |
Роман Долгополов (RDOL)
|
|
|
13.09.2010, 16:05 | #23 |
Ищущий знания...
|
Цитата:
Сообщение от sukhanchik
Учитывая как сильно последнее время отличаются между собой версии - эта "мелочь" потонет при апгрейде. Да и пригодится-то она только в своих модификациях только, которых не должно быть много .
По поводу констант - от их использования никуда не убежишь. И их использование заменяется использованием макросов. Если бы можно было бы от констант отказаться - то давно б отказались. Не приветствуется использование таких констант, которые не могут быть константами - ставка налога к примеру. А какие-то вещи - типа количество дней в году, или "волшебный номер" 255 - вполне может использоваться. Как раз-таки его и не потребовалось бы использовать - если бы все енумы начинались бы с нулевого ничего не значащего значения. под не использованием нулевого значения, я не имел ввиду создание элементов начиная с 1. Имелось в виду создания Первого элемента как None = 0, которое не имеет смысловой нагрузки, а используется как пустое значение.
__________________
"Страх перед возможностью ошибки не должен отвращать нас от поисков истины." (с) С Уважением, Елизаров Артем |
|
13.09.2010, 16:10 | #24 |
Ищущий знания...
|
Цитата:
P.S. наше обсуждение ушло немного в сторону от исходной темы, приношу свои извинения топикстартеру
__________________
"Страх перед возможностью ошибки не должен отвращать нас от поисков истины." (с) С Уважением, Елизаров Артем |
|
13.09.2010, 16:11 | #25 |
Administrator
|
Цитата:
В такой постановке абсолютно согласен.
__________________
Возможно сделать все. Вопрос времени |
|
13.09.2010, 16:12 | #26 |
Роман Долгополов (RDOL)
|
Да я бы рад, только что делать с каким нибудь, например, SalesType?
|
|
13.09.2010, 16:24 | #27 |
Ищущий знания...
|
ждал этого вопроса
если вам нужно выполнить обработку по заказам, и эта обработка должна быть параметризирована, то я бы для обработки создал свой Enum, с помощью которого бы определялось, выполнять обработку по заказам с SalesType = Journal или Sales. Конечно это более трудозатратно чем просто передать в параметре SalesType, но в случае с уже существующими (системными) enum-ами, где нулевой элемент несет смысловую нагрузку, это гарантирует что все проверки по параметру отработаю корректно, и все необходимые заказы будут обработаны. Вот как то так
__________________
"Страх перед возможностью ошибки не должен отвращать нас от поисков истины." (с) С Уважением, Елизаров Артем |
|
13.09.2010, 16:33 | #28 |
Роман Долгополов (RDOL)
|
Цитата:
Сообщение от lev
ждал этого вопроса
если вам нужно выполнить обработку по заказам, и эта обработка должна быть параметризирована, то я бы для обработки создал свой Enum, с помощью которого бы определялось, выполнять обработку по заказам с SalesType = Journal или Sales. Конечно это более трудозатратно чем просто передать в параметре SalesType, но в случае с уже существующими (системными) enum-ами, где нулевой элемент несет смысловую нагрузку, это гарантирует что все проверки по параметру отработаю корректно, и все необходимые заказы будут обработаны. Вот как то так Идеального универсального решения для этой задачи нет. Выбираем на свой вкус и пользуемся при необходимости. Вкусы можно менять в зависимости от ситуации Предлагаю на этом закончить |
|
13.09.2010, 16:57 | #29 |
Участник
|
|
|
|
За это сообщение автора поблагодарили: db (1), sukhanchik (3). |
20.06.2011, 15:19 | #30 |
Участник
|
В сто пятидесятый раз попал в туже ситуацию и решил разобраться в вопросе.
Итак, изначальная постановка Wamr была: как правильно реализовать серверный обработчик (плюс который нормально будет работать в пакете) с параметрами, изменяемыми в диалоге. Само собой этот параметр будет в списке тех, которые сохраняются в pack() и поэтому если мы этот параметр parm-методом зададим он перетрётся старым значением. Есть предложение db писать в таких случаях в main(): .getLast() .parmXXX(...) .saveLast() Я так тоже делал, но такой метод мне не нравится, так как во-первых, сохраняет уже сразу после вызова, даже если мы отменим выполнение в диалоге и во-вторых, если класс сделан с запросом на QueryRun (который сохраняется в pack()), то нужно уже на этом этапе как-то его инициализировать. sukhanchik предложил просто такие параметры не "распаковывать" если они не пусты, признав далее извращенность такого решения. И далее дискуссия ушла в обсуждение Enum-ов, чего касаться я вообще не хочу. Собственно я предлагаю такой вариант: 1. В classDeclaration добавить макрос со списком параметров, которые будут меняться в диалоге, например: X++: #localmacro.ParamsList param1, param2 #endmacro X++: public boolean unpack(container packedClass) { Version version = runbase::getVersion(packedClass); container params = [#ParamsList]; switch (version) { case #CurrentVersion: [version,#CurrentList] = packedClass; if (this.inGetSaveLast()) [#ParamsList] = params; break; default: return false; } return true; } Единственное надо проверить, чтобы на всех версиях аксапты параметр inGetSaveLast вёл себя одинаково. Ну и в минусы можно записать то, что этот список нужно не забывать пополнять по мере доработки класса (версионность тут вроде не нужна). Подводных камней вроде не вижу. Что скажете? |
|
20.06.2011, 15:29 | #31 |
Участник
|
2 leva
А не проще написать свой конструктор, а в нем : X++: static construct() { ret = New runBase_...child(); ; ret.getLast(); return ret; } писать runBase_...child::construct() всегда так делаю и проблем вроде не было. плюс так правильнее писать. В дальнейшем легче код поддерживать если потребуется везде использовать другого наследника. подправил contruct и все. |
|
20.06.2011, 15:46 | #32 |
Участник
|
Т.е. идея в том что вы сперва все параметры распаковали, а потом уже поверх них записали все параметры, какие надо. Сохранения сразу после вызова при таком подходе тоже нет. (Хотя не вижу в нем ничего плохого. Кому оно может помешать ?)
|
|
20.06.2011, 15:50 | #33 |
Участник
|
Ну и дальше что? Вызываем prompt() который опять перетирает все параметры.
|
|
20.06.2011, 15:58 | #34 |
Участник
|
Цитата:
Он при вызове getLast() взводит некий флажок. Так что при вызове Prompt() повторного вызова getLast() и, соответственно, перезатирания не происходит. |
|
|
За это сообщение автора поблагодарили: leva (1). |
20.06.2011, 16:27 | #35 |
Участник
|
Действительно, и как я не заметил. И почему-то такое, лежащее на поверхности решение, тогда никто не предложил.
Но есть правда один момент, бывает что в unpack создается queryRun, который в свою очередь может зависеть от этого параметра. Тут конечно можно вызвать перестроение запроса после всех parm-ов, но хотелось бы не выносить заботу о таких вещах из класса. Ну и подводный камень в своем решении нашел - если getLast() будет вызван ни для заполнения формочки, а с какой-то другой целью в этих параметрах будет пустота. |
|
20.06.2011, 16:38 | #36 |
Участник
|
Нашёл как обойти подводный камень с неверным поведением unpack в других случаях - нужно добавить к this.inGetSaveLast() && inPrompt
Может показаться, что я тут фигней занимаюсь, но хочется написать универсальную, красивую и максимально корректную рыбу, чтобы голову больше этим не забивать. |
|
20.06.2011, 17:36 | #37 |
Участник
|
Ну, если решение через Construct - не нравится, то можно пойти "другим путем"
Если сделать допущение, что имя параметра вовсе не обязано совпадать с именем сохраняемой в pack/unpack переменной, то все решается значительно проще. Через parmXXX() записываем переменную parmXXX, а в методе RunBase.dialog() при создании объектов формы диалога пишем примерно следующее X++: dialogField = dialog.addFieldValue(typeid(MyType), parmXXX ? parmXXX : unpackYYY); Если передан параметр (parmXXX), то он инициализирует значение объекта на форме диалога и он же будет сохранен, если пользователь его не изменит. Если же параметр не передан, то инициализировать значение объекта на форме диалога будет распакованное значение переменной. С Query - чуть сложнее, но тоже не особо. Ведь в любом случае должен быть метод по его созданию. Вот в этом методе и анализировать значение параметра. В любом случае "разведение" переданных и сохраненных значений по разным переменным значительно упростит как анализ, так и кодирование. |
|
|
За это сообщение автора поблагодарили: S.Kuskov (2). |
21.06.2011, 08:15 | #38 |
Участник
|
Цитата:
Цитата:
Вот мой вариант с Query. Здесь initQuery тот самый метод, что строит запрос (на основе переданного в качестве параметра). X++: public boolean unpack(container packedClass) { Version version = runbase::getVersion(packedClass); container packedQuery; Query query; container params = [#ParamsList]; switch (version) { case #CurrentVersion: [version, #CurrentList, packedQuery] = packedClass; if (packedQuery && SysQuery::isPackedOk(packedQuery)) query = new Query(packedQuery); if (! query) throw error("Ошибка"); if (inPrompt && inGetSaveLast) { [#ParamsList] = params; queryRun = new QueryRun(this.initQuery(query)); } else queryRun = new QueryRun(query); break; default: return false; } return true; } |
|
21.06.2011, 08:59 | #39 |
Участник
|
Мне кажеться логичным в принципе разделить и не смешивать эти два случая, а точнее не смешивать сами сохраняемые значения. Пусть при запуске через форму будет вестись своя история последних значений, а при запуске из главного меню - своя. Для этого достаточно переопределить один из методов интерфейса SysSaveable (например: lastValueType), в котором возвращать параметр передавыемый через менюайтем и не париться по поводу ручного разруливания сохранённых значений.
|
|
21.06.2011, 10:00 | #40 |
Участник
|
leva
Описанная задача не то, чтобы совсем уж невозможная, но достаточно экзотическая. sukhanchik уже пытался намекнуть на это. Да и S.Kuskov говорит о том же. Ну, не может один и тот же класс и принимать значение из-вне и доставать это же самое значение из кеша. Не в смысле того, что физически не может, а в том смысле, что подобная задача свидетельствует о том, что у Вас большие проблемы в организации структуры классов. Как минимум, это должно быть два разных класса. Один - предназначенный для извлечения значения параметра из кеша, а другой - для приема параметров из-вне класса. И попытка "смешать" две разные задачи в одном классе ничего кроме проблем Вам не принесет. Не надо пытаться сделать один супер-класс на все случаи жизни. Не то, чтобы это было совсем уж невозможно, но практического смысла в этом нет. Два отдельных класса и проще сделать, и проще сопровождать. |
|