15.09.2017, 19:04 | #1 |
Участник
|
Edit Method
Ax 4
Всем доброго дня. Подскажите реально ли сделать следущее. Есть форма заказов на продажу. На форме три grid. Самый верхний шапка заказа на продажу. Второй строки заказа на продажу с основными товарами. Третий грид тоже отображает строки заказа, но это строки с дополнительными товарами которые относятся в выбранному основному товару (связь через RefRecId на строку основного товара). В третьем grid есть дисплейный метод который отображает внутренний код основного товара из InventTable. Появилась потребность изменение основного товара у дополнительного. Чтобы не удалять и заново создавать записи в третьем grid, есть ли возможность вывести туда edit method который будет отображать внутренний код основного товара и при изменении его прописывать новый RefRecId в строки дополнительного товара? |
|
15.09.2017, 19:19 | #2 |
Участник
|
во-первых, удаляются и создаются записи не в гриде, а в базе данных. грид всего лишь отображает.
во-вторых, я не очень понимаю смысл и цель условия "не удалять и не создавать заново". Представьте, что у вас многопользовательская система. с одним заказом могут работать несколько пользователей одновременно, выполняя разные задачи. каждый видит свой мастер-дитейл. каждый может использовать сложную систему кэширования (простейшая - свойство таблицы CacheLookup=NotInTTS). У каждого может быть включен фильтр на уровне записей. и вот вы собираетесь изобрести хитрый способ изменить хитрые отношения в мастер-дитейл таблицах, не удаляя и не пересоздавая записи? зачем? чтобы потом героически решать проблемы с кэшами и прочими инструментами? Чтобы потом делать find и обязательно проверять тот ли RecRefId в найденной записи? ================== если вас смущает необходимость копировать поля в новую запись, то давно существует метод buf2buf. используйте его. |
|
15.09.2017, 19:26 | #3 |
Участник
|
Хотелось бы сделать максимально простой способ изменения основного товара для пользователя. Я расчитывал на то, что если один из пользователей уже сменит основной товар и это попробует сделать другой пользователь, то Аксапта бодро отрапортует "Данные на форме не являются текущими".
|
|
15.09.2017, 19:53 | #4 |
Участник
|
Цитата:
скорее всего, нет. а он отображается, если первый уже изменил, а второй еще не сделал research. в результате у другого пользователя возможно состояние с нарушенным инвариантом. нарушенный инвариант очень тяжело отследить на той же самой записи. впрочем, как хотите Цитата:
но такое поведение будет неожиданным для всех, включая саму аксапту. |
|
15.09.2017, 20:17 | #5 |
Участник
|
Давно не работал с edit методами. Подскажите что делаю не так
X++: edit Out_ItemId outId_1CMaster( boolean _set, Out_ItemId _out_itemId) { InventTable inventTableLocal; Out_ItemId ret; ; inventTableLocal = InventTable::find(salesLineSlave.salesLineMaster().ItemId); return inventTableLocal.OutId_1C; } |
|
15.09.2017, 20:33 | #6 |
Участник
|
давайте я прочитаю ваш код на человеческом языке:
1. игнорировать режим _set = dispaly or edit 2. игнорировать второй параметр - значение которое ввел пользователь 3. найти номенклатуру с каким-то левым itemId 4. возвратить для отображения на экране код OutId_1C для найденной номенклатуры при этом не запоминать никаких значений. ни в датасорсах, ни в таблицах. да, думаю, что стоит просто почитать доку по ключевым словам "edit method" и посмотреть примеры. Последний раз редактировалось mazzy; 15.09.2017 в 20:42. |
|
15.09.2017, 21:12 | #7 |
Участник
|
Я ведь написал что просто пытаюсь вывести внутренний код
Метод у меня выглядит вот так X++: edit Out_ItemId outId_1CMaster( boolean _set, Out_ItemId _out_itemId) { InventTable inventTableLocal; Out_ItemId ret; ; if (_set) { inventTableLocal = InventTable::findOut_1C(_out_itemId); salesLineSlave.SalesLineMaster = SalesLine::findItemId(salesTable.SalesId, inventTableLocal.ItemId).RecId; } inventTableLocal = InventTable::find(salesLineSlave.salesLineMaster().ItemId); return inventTableLocal.OutId_1C; } так как проблема с выводом кода, то в предыдущий раз метод представил в укороченном виде |
|
15.09.2017, 21:37 | #8 |
Участник
|
Цитата:
Цитата:
а что показывает отладчик? похоже, что в голове нужно уложить две вещи: 1. есть записи в базе (это не грид и не переменные) 2. гриды, датасорсы и переменные могут содержать значения, которые когда-то были прочитаны из базы. эти копии могут не совпадать с актуальными значениями в базе. любой query/select ищет не в переменных, а в базе. чтобы из переменных сохранить в базу, нужно вызывать метод insert/update. ========================= сохранять значения в базу внутри метода edit можно. но такое поведение будет неожиданным не только для программистов и для аксапты, но и для пользователей. Последний раз редактировалось mazzy; 15.09.2017 в 21:54. |
|
15.09.2017, 22:03 | #9 |
Участник
|
и видите ли в чем дело...
в заказе может быть несколько строчек с одинаковой номенклатурой. поэтому сам подход вот с таким поиском - принципиально неверный с точки зрения бизнес-функционала. |
|
15.09.2017, 22:20 | #10 |
Участник
|
Да метод содержит select, но я пока не говорю про обновление записей. Просто хожу по строкам и вижу в edit методе не то что надо. В моем примере 3 строки с дополнительным товаром. У каждой из строк свой основной товар. На выделенной строке все верно, а на одной из оставшихся такое-же значение как и на первой, на третьей все верно.
|
|
15.09.2017, 22:40 | #11 |
Участник
|
Цитата:
поэтому сам подход вот с таким поиском - принципиально неверный с точки зрения бизнес-функционала
|
|
15.09.2017, 22:48 | #12 |
Участник
|
Цитата:
но будет лучше, если все поля в одном гриде будут принадлежать одному датасорсу. |
|
16.09.2017, 01:06 | #13 |
Banned
|
Цитата:
Сопутствующие товары должны быть представлены в системе как набор со своим ID. Голова набора и строки набора. Ещё одна новая таблица - связующая для связи строки заказа и набора. Смена основного товара на строке никак не влияет на этот набор. При изменении строк в наборе сопутствующих товаров менятся значение ID набора в связывающей таблице которая по сути два поля, сама строка заказа не меняется. P.S. Не обязательно при этом менять ID набора как это делается с InventDimId, можно и тупо держать тот же RecId головы набора в качестве такого ID уникального для строки заказа, так даже проще. Просто на практике сопутствующие товары часто предопределённый набор. Постановка задачи нормальна. Ненормально буквально её воспринимать и искать техническую логику. Последний раз редактировалось ax_mct; 16.09.2017 в 01:37. Причина: ps |
|
16.09.2017, 11:08 | #14 |
Участник
|
Цитата:
не получилось ли так, что на одном гриде у вас присутствуют поля с разными датасорсами? если так, то тип связи между этими датасорсами должен быть равен InnerJoin.
SalesTable SalesLineMaster (Delayed) InventTableMaster (InnerJoin) SalesLineSlave (Delayed) InventTableSlave И сейчас в edit методе мне нужно отобразить OutId_1C из InventTableMaster. Получается это в данном случае нереализуемо. Я правильно понял? |
|
16.09.2017, 11:11 | #15 |
Участник
|
Цитата:
может вы просто подготовите проект с необходимым минимумом и положите сюда? |
|
16.09.2017, 11:57 | #16 |
Участник
|
Подготовил проект.
|
|
18.09.2017, 11:32 | #17 |
Участник
|
Точно помню что пробовал передавать 3 параметра и это у меня не получалось. Сейчас все норм.
X++: public edit Out_ItemId outId_1CMaster( boolean _set, SalesLine _salesLineSlave, Out_ItemId _out_itemId) { InventTable inventTableLocal; Out_ItemId ret; ; if (_set) { inventTableLocal = InventTable::findOut_1C(_out_itemId); salesLineSlave.SalesLineMaster = SalesLine::findItemId(salesTable.SalesId, inventTableLocal.ItemId).RecId; } inventTableLocal = InventTable::find(_salesLineSlave.salesLineMaster().ItemId); return inventTableLocal.OutId_1C; } |
|
|
За это сообщение автора поблагодарили: mazzy (2). |
|
|