11.04.2017, 15:30 | #1 |
Участник
|
Мультипаспорт записи
Вниманию участников форума предлагается утилита «Мультипаспорт записи», в дальнейшем именуемая как «мультипаспорт», предоставляет возможности для редактирования данных в полях на формах Аксапты. Она не замещает имеющийся «Паспорт записи» и используется независимо от него.
Основные преимущества перед обычным паспортом записи: 1) Вызывается из любой формы Аксапты без использования мыши. 2) Позволяет выполнять скрипты для вычисляемых значений, например ----- а) можно поменять знак в количестве во всех строках документа ----- б) добавить префикс к кодам сразу нескольких номенклатур ----- в) сменить цену в заказе и пересчитать сумму по строке ----- г) присвоить значение полю из другого поля. ----- д) выполнить скрипт любой сложности ----- е) использовать любые классы или джобы Аксапты ----- ж) скрипты можно использовать для тестирования ваших доработок без добавления новых кнопок на формы Аксапты 3) Позволяет изменять значения сразу в нескольких источниках данных на форме. Например, вы можете изменить код номенклатуры сразу в нескольких таблицах, которые отображаются на форме "Сведения о продукте" 4) Можно изменить значение поля сразу для всех отфильтрованных на форме Аксапты записей. В поле можно ввести константу - тогда всем записям присвоится одинаковое значение. Или можно выполнить скрипт - тогда значения для каждой записи будет вычислено отдельно. 5) Можно массово изменять данные в строках документов, фильтруя их по заголовкам документов. Например, отфильтровать заказы на продажу для определенного клиента и во всех строках умножить цену на 2. 6) Можно изменять складские аналитики налету. Например поменять склад во всех строках одного заказа на продажу или даже во всех заказах, отфильтрованных по нужным вам признакам. Просто меняете один склад на другой, и мультипаспорт сам подставит нужный код комбинации складских аналитик в строку документа. 7) Можно объединять поля в одной или разных таблицах в наборы. И потом используя эти наборы полей просматривать и изменять сгруппированные по смыслу данные. В прилагаемой документации описаны основные приемы работы с мультипаспортом. Во вложении описание утилиты и проекты для Аксапты версий 2012, 2009 и 3.0. Переносить нужно все объекты в проектах кроме одного - они не затрагивают стандартный функционал. Класс SysSetupFormRun переносить целиком не нужно. Достаточно добавить строку следующую строку кода перед непосредственным вызовом super() в методе task(). X++: if (!zRecordInfo::recordInfoOverloadButton(_p1, this)) Последний раз редактировалось sukhanchik; 21.04.2017 в 18:46. |
|
|
За это сообщение автора поблагодарили: bitter (1), raz (10), Logger (10), S.Kuskov (10), KiselevSA (5), Dron AKA andy (5), sukhanchik (10), ivas (3), MazZzDaI (1), trud (5), rumpleteazer (1), Dumfag (1), imir (2). |
11.04.2017, 16:00 | #2 |
Участник
|
|
|
|
За это сообщение автора поблагодарили: Ace of Database (1). |
11.04.2017, 22:59 | #3 |
Участник
|
Прошу модераторов поправить мое первое сообщение.
Поправка: в классе SysSetupFormRun надо перед непосредственным вызовом super() в методе task() добавить следующую строку кода X++: if (!zRecordInfo::recordInfoOverloadButton(_p1, this)) **sukhanchik** Поправлено Последний раз редактировалось sukhanchik; 21.04.2017 в 18:46. |
|
12.04.2017, 10:30 | #4 |
Участник
|
Исправил один баг для AX3.0. В новых версиях этот баг уже учтен, а в АЗ.0 он в тех же местах не воспроизводился. Но сегодня воспроизвелся на форме "Налоговые операции", которая открывается по кнопке "Разнесенные налоги" на журнале накладных. Патч во вложении.
|
|
13.04.2017, 09:42 | #5 |
Участник
|
Сегодня встретилась форма, на которой программно дизэйблится источник данных. Из-за этого не работало массовое изменение в строках документа на сильно модифицированной форме закупок.
Чтобы не включать в сгенерированный мультипаспортом запрос задизэйбленные источники, надо добавить в классе zRecordInfo в методе fillQueryTreeQueryDatasource в самую первую строку кода после декларации переменных вставить следующий код: X++: if (!queryBuildDatasource.enabled()) return; PS: прошу прощение за слово "дизэйблится" |
|
17.04.2017, 14:28 | #6 |
Участник
|
|
|
17.04.2017, 15:05 | #7 |
Участник
|
Я как раз сейчас в гитхабе лазию. Меня заставила перейти туда вот такая штука:
http://plnkr.co/edit/?p=catalogue Пытаюсь сделать оффлайн html-редактор документов Аксапты. Но до этого еще далеко. А какие бонусы мне может дать проект на GitHub с переводом на английский? |
|
19.04.2017, 15:11 | #8 |
Участник
|
Выяснилось, что в Аксапте неправильно работает метод SysQuery::countTotal().
Из-за этого при установленных галках "Выполнить для всех записей текущего родителя" или "Выполнить для всех записей, отображаемых на форме" мультипаспорт подвисал, пока этот метод не подсчитает все записи во всех таблицах запроса. Я это сразу не заметил, так как в основном тестировал на той Аксапте, где метод SysQuery::countTotal() уже был переделан умельцами. В итоге я решил исправить по-другому. В классе SysQuery сделал новый клиентский статический метод countPrimClient. Метод работает на клиенте, чтобы не гонять QueryRun через клиент-сервер. Так как по моим ощущениям, при этом могут теряться dynalink и еще что-то, я уже не помню что. Чтобы у вас в мультипаспорте плавно работал прогресс-бар при массовом изменении данных, а также чтобы перед массовым изменением данных мультипаспорт не подвисал, то произведите два следущих изменения: 1) В класс SysQuery добавьте следующий метод X++: client static int countPrimClient(Query _query) { Query countQuery; QueryRun countQueryRun; QueryBuildDataSource qbds; QueryBuildFieldList qbfl; Common common; int counter; int loops; int iGrp; int k ; countQueryRun = new QueryRun(_query); countQuery = countQueryRun.query(); for (k = 1; k <= countQuery.dataSourceCount();k++) { qbds = countQuery.dataSourceNo(k); qbds.update(false); iGrp +=(qbds.orderMode()==orderMode::GroupBy); // SHiSHok.fix //qbds.sortClear(); // Вот этот метод сильно мешал! qbfl = qbds.fields(); qbfl.dynamic(false); qbfl.clearFieldList(); qbfl.addField(FieldNum(Common,recId),SelectionField::COUNT); } countQueryRun = new QueryRun(countQuery); while (countQueryRun.next()) { common = countQueryRun.getNo(1); counter += common.recId; loops++; } // return [counter,((loops > 1)? loops : counter)]; return counter; } строку кода X++: p.setTotal(SysQuery::countTotal(queryRun)); X++: p.setTotal(SysQuery::countPrimClient(query)); Количество строк в Query |
|
21.04.2017, 13:01 | #9 |
Участник
|
В 12-шке На сложных формах типа договоров поставщиков валится с ошибками типа поле не было явным образом выбрано
|
|
|
За это сообщение автора поблагодарили: Ace of Database (2). |
21.04.2017, 14:50 | #10 |
Участник
|
Я понял, это таблицы с иерархией.
В таблице PurchAgreementHeaderExt_RU нет поля relationType. Но оно есть в базовой таблице AgreementHeaderExt_RU. Буду думать, как из этого можно сварить суп. Точнее, этого поля даже в базовой таблице нет в AOT, но оно есть физически в базе SQL Можно выполнить такой запрос SQL select relationType, * from AGREEMENTHEADEREXT_RU Последний раз редактировалось Ace of Database; 21.04.2017 в 14:53. |
|
21.04.2017, 15:38 | #11 |
Участник
|
Ловите патч для AX2012
|
|
|
За это сообщение автора поблагодарили: Pustik (12). |
24.04.2017, 10:54 | #12 |
Участник
|
Продолжение темы с наследуемыми таблицами в AX2012.
Во вложении патч, который исправляет проблему того, что в мультипаспорте не были видны поля из иерархических таблиц (например, не было видно поля "Дата" договора). В стандартном паспорте такие поля тоже не видны, а в мультипаспорте - теперь видны! Еще один повод использовать мультипаспорт Есть следующие особенности для наследуемых таблиц: 1) Если поменять через мультипаспорт дату или сумму договора, то эти поля перерисуются на стандартной форме не в момент сохранения записи в мультипаспорта, а только после того как вы закроете мультипаспорт. Обычные поля перерисовываются сразу после сохранения в мультипаспорте. При множественном изменении данных записи перерисовываются сразу и для суммы и для даты договора. 2) Поле "Классификатор договора" мультипаспорт отображает, но не может определить его в тот момент, когда вы нажимаете клавиши ALT+1 для активации мультипаспорта при фокусе ввода, находящемся в этом поле. Мультипаспорт не позиционируется на это поле и выдает инфолог "Фокус не был установлен на выбранное поле. Найдите поле вручную." Ищите это поле в мультипаспорте вручную Также в этот патч включено исправление для подсчета количества изменяемых записей при множественном изменении данных (смотрите на четыре сообщения выше от этого сообщения). Класс SysQuery. Последний раз редактировалось Ace of Database; 24.04.2017 в 10:58. |
|
|
За это сообщение автора поблагодарили: KiselevSA (5). |
15.05.2017, 15:20 | #13 |
Участник
|
Все обновления по утилите "Мультипаспорт" теперь буду выкладывать в моем блоге
http://aceofdatabase.blogspot.com/ Сейчас там последняя версия со всеми исправлениями, перечисленными здесь, плюс устранен сбой при вызове мультипаспорта из формы мастеров. В свободное время буду выкладывать туда свои утилиты. У меня их примерно около пяти.
__________________
Мои утилиты для Аксапты версий 3.0-2012: http://aceofdatabase.blogspot.com/ |
|
15.05.2017, 16:09 | #14 |
Участник
|
может все же лучше выкладывать проекты на github?
добавил в импорт блогов. спасибо. |
|
15.05.2017, 16:40 | #15 |
Участник
|
Хорошо, попробую через GitHub, раз это актуально.
__________________
Мои утилиты для Аксапты версий 3.0-2012: http://aceofdatabase.blogspot.com/ |
|
|
За это сообщение автора поблагодарили: mazzy (2). |
06.06.2017, 14:59 | #16 |
Участник
|
Выложил проект для AX2012 на GitHub
https://github.com/farmer1357/AX2012...rt-Project.git Использовал для экспорта проекта вот эту штуку https://community.dynamics.com/ax/b/...namics-ax-2012 Чтобы она у меня заработала, прописал корректный путь к файлу Git.exe в методе classDeclaration класса Git X++: class Git { #localmacro.git @'C:\Program Files\Git\bin\git.exe' #endmacro #localmacro.TortoiseGit @'C:\Program Files\TortoiseGit\bin\TortoiseGitProc.exe' #endmacro }
__________________
Мои утилиты для Аксапты версий 3.0-2012: http://aceofdatabase.blogspot.com/ |
|
|
За это сообщение автора поблагодарили: mazzy (2), Logger (2). |
08.06.2017, 12:52 | #17 |
Участник
|
Добрый день!
Для поля с ExtendedDataType==PackedQueryRun вылетает ошибка. PHP код:
PHP код:
PHP код:
Последний раз редактировалось mdanko2000; 08.06.2017 в 13:20. Причина: дополнил |
|
|
За это сообщение автора поблагодарили: Ace of Database (2). |
08.06.2017, 14:36 | #18 |
Участник
|
А как таблица называется? Чтобы на ней потренироваться.
__________________
Мои утилиты для Аксапты версий 3.0-2012: http://aceofdatabase.blogspot.com/ |
|
08.06.2017, 14:49 | #19 |
Участник
|
Не думаю что это поможет , таблица называется ExportXMLExcelMainTable.
Я у себя поменял dictField.Type() на dictField.baseType() и всё заработало. Ну и как пожелание, при переходе по дереву таблиц может имеет смысл фильтровать данные в гриде для текущей таблицы ? |
|
29.03.2022, 09:30 | #20 |
Участник
|
Таблица: zRecordInfoTmp
Метод: zRecordInfoTmp X++: static zRecordInfoTmp fillForRecord(Common record, zRecordInfoTmp _zRecordInfoTmp = null, str _dsName = "", int _dsNum = 0, int _repeatCount = 1) { zRecordInfoTmp zRecordInfoTmp; DictTable dictTable; DictField dictField; int fieldCnt; int i; int j; int arraySize; str ts; ; if (_zRecordInfoTmp) zRecordInfoTmp = _zRecordInfoTmp; dictTable = new DictTable(record.TableId); fieldCnt = dictTable.fieldCnt(); for (i = 1; i <= fieldCnt; i++) { dictField = dictTable.fieldObject(dictTable.fieldCnt2Id(i)); arraySize = dictField.arraySize(); for (j = 1; j <= arraySize; j++) { if (dictField.isSql()) { //w(dictField.); zRecordInfoTmp.clear(); zRecordInfoTmp.FormDatasourceNum = _dsNum; zRecordInfoTmp.FormDatasourceName = _dsName; zRecordInfoTmp.RefRecId = record.RecId; zRecordInfoTmp.TableName = dictTable.name(); if (_dsName && _repeatCount > 1) zRecordInfoTmp.TableName += strfmt(" [%1]", _dsName); zRecordInfoTmp.RefTableId = dictTable.id(); zRecordInfoTmp.RefFieldName = dictField.name(DbBackEnd::Native, j) + (arraySize > 1 ? strFmt('[%1]', j) : ""); zRecordInfoTmp.RefFieldId = dictField.id(); zRecordInfoTmp.FieldArrayIdx = j; zRecordInfoTmp.FieldLabel = dictField.label(j); if (dictField.type() == Types::Time) { zRecordInfoTmp.FieldValue = time2str(record.(fieldid2ext(dictField.id(), j)), 1, 1); } else if (dictField.type() != Types::Container && dictField.baseType() != Types::Container // <------ fix ) { ts = strfmt("%1", dictField.type()); zRecordInfoTmp.FieldValue = strfmt("%1", record.(fieldid2ext(dictField.id(), j))); } else { zRecordInfoTmp.FieldValue = "[Container]"; } zRecordInfoTmp.insert(); } } } return zRecordInfoTmp; } Если имеется таблица у которой поле является EDT который в свою очередь является производным от Extends который в свою очередь с типом Container. Тогда вылетает ошибка. Последний раз редактировалось oleggy; 29.03.2022 в 09:34. |
|
|
За это сообщение автора поблагодарили: S.Kuskov (2). |
Теги |
github |
|
|