11.01.2007, 14:37 | #1 |
Участник
|
снятие данных с GRID
Как доступиться до значений полей уже открывшегося грида ?
датасорс не подходит, т.к. дисплейные методы могут иметь место... как исследуя treenode...снять данные с грида? |
|
11.01.2007, 14:44 | #2 |
Участник
|
а не пробовал дисплейный метод пересчитать? Тогда с ДС сдернеш данные
__________________
Рабочий день сокращает жизнь на 8 часов |
|
11.01.2007, 15:01 | #3 |
Участник
|
Тогда нужно знать где он тот дисплейный метод..на датасорсе, на таблице...
а это ещё кусок кода, причем не малый... Давайте разберемся на примере. Я открыл SalesTable (расячеты с клиентами/закупки). Там 3 датасорса (SalesTable, SalesLine, InventDim)...Логично бы сказать что главный датасорс SalesTable, Ну допустим я из X++ выясню какой из датасорсов главный...определю как линкуются другие...А как быть с дисплей методами... В общем все очень сложно как-то... А нельзя ли с грида снять? |
|
11.01.2007, 15:17 | #4 |
Участник
|
Цитата:
похоже, вы начинаете писать некий "универсальный обработчик". Я уже говорил, что необходимость в универсальном обработчике возникает, как правило, в тех случаях, когда программист мало знает о предметной области... Попытка программистов делать "универсальные обработчики" зачастую приводит к тому, что вместо реальных задач клиентов решаются некие программистские задачи (остальным не нужные и не интересные). Так например,... Во-вторых, Вместо нормальных дисплейных методов вы будете вынуждены разбираться с типами этих контролов. Так значение строкового контрола читается одним методом, значение даты читается другим методом, значение enum читается третьим методом и т.п. Другими словами при создании вашего "универсального обработчика" вы с удовольствием будете заниматься программисткими задачами, которые мало приблизят вас к решению задачи, потому что... В-третьих, при работе с контролами вам придется заниматься вопросами безопасности вручную. Поле, с которым связан контрол может быть запрещено конфигурационным ключом, секьюрити ключом, либо настройками пользователя. Скрытые контролы не рассчитываются и не получают никаких значений. Таким образом, вместо того, чтобы заниматься задачами пользователей, вы будете заниматься обеспечением нескрываемости нужных вам контролов. Но это еще не все... В чертвертых, вы будете бороться со штатным механизмом кэширования. Почитайте о кэшировании, о свойстве NotInTts. И это не все. В пятых, вы будете материться на штатный механизм проверки измененных данных. Аксапта - многопользовательская система. И данные, введенные в форму перед записью проверяются - "а не изменил ли кто введенные данные?". А считанное из контрола значение может не совпадать с текущим значением в базе... и т.д. Там еще много подводных камней... Не дай бог вы начнете использовать ListView (как это сделано в оборотно-сальдовых ведомостях и в налоговом учете). В общем, займитесь решением задачи ваших клиентов. Не тратьте время на интеллектульный онанизм. ЗЫ: если вы сейчас начнете говорить, что делаете системную утилиту... Пожалуйста не надо. Вам пока лучше воздержаться от создания системных утилит. Приступайте к ним после того, как разберетесь со штатными возможностями ядра. |
|
11.01.2007, 15:23 | #5 |
Участник
|
Цитата:
Сообщение от PODOL
Тогда нужно знать где он тот дисплейный метод..на датасорсе, на таблице...
а это ещё кусок кода, причем не малый... Давайте разберемся на примере. Я открыл SalesTable (расячеты с клиентами/закупки). Там 3 датасорса (SalesTable, SalesLine, InventDim)...Логично бы сказать что главный датасорс SalesTable, Ну допустим я из X++ выясню какой из датасорсов главный...определю как линкуются другие...А как быть с дисплей методами... В общем все очень сложно как-то... А нельзя ли с грида снять?
__________________
Рабочий день сокращает жизнь на 8 часов |
|
11.01.2007, 15:24 | #6 |
Участник
|
2 mazzy: Жестоко, конечно, но по делу.
Только вот не понял в первых двух пунктах многоточия вконце? Это забыл дописать, или надо додумать самому? |
|
11.01.2007, 15:27 | #7 |
Участник
|
Мне кожется экономия времени, но могу и ошибаться, примеры могут занять много времени, которое щас стоит денег
__________________
Рабочий день сокращает жизнь на 8 часов |
|
11.01.2007, 15:43 | #8 |
Участник
|
Это переход на следующий пункт читать следует подряд единым текстом.
Пока пиал ответ, столько контраргументов в голову пришло. Писать полный перечень действительно лениво. Наличие контраргументов вовсе не означает, что такого никогда делать не надо. Но такими извращенно-хакерским способам доступа должен пользоваться человек, хорошо изучивший стандартный функционал. ИМХО. |
|
11.01.2007, 16:18 | #9 |
Участник
|
я всего лишь хотел узнать...
1. я ещё не начал его писать,..я просто у более опытных интересуюсь по силам ли, вот и всё 2. выбрасыая всё наружу ч-з COM мне не так интересно, что там за тип переменной 3. скрытые контролы меня не интересуют...мне важно, лишь то что видит пользователь...(но проблема серьзная, я об ней не подумал) 4. м-да... 5. мне пофиг...ситуация аналогичная постройке отчета...в данный момент и всё...(после init формы) |
|
11.01.2007, 16:44 | #10 |
Banned
|
Формально снять информацию с грида нельзя, поскольку адресовать можно только поля грида, соответсвуюшие текущей записи (т.е. только активную строку). Именно из-за этого глубокого ограничения российские разработчики использовали ListView там, где они его использовали.
|
|
11.01.2007, 16:55 | #11 |
Участник
|
Цитата:
То, что российские разработчики использовали ListView там, где они его использовали, является на мой взгляд грубейшей ошибкой. Именно это решение приводит к катастрофичным последствиям для тех, кто внедряет... столько подзатыльников и пинков под зад... |
|
11.01.2007, 17:12 | #12 |
Программатор
|
А если пользователь хочет на закладке формы увидеть что то типа истории продаж в разрезе складов например. А в ходе работы количество складов может изменятся, тогда как эту историю хранить в таблице и выводить в грид????(хранить то можно, но вот вывести....)
Последний раз редактировалось Sada; 11.01.2007 в 17:18. |
|
11.01.2007, 17:46 | #13 |
Участник
|
поскольку адресовать можно только поля грида, соответсвуюшие текущей записи (т.е. только активную строку)
а потом двигаться next-om как по датасорсу...так можно? |
|
11.01.2007, 17:49 | #14 |
Banned
|
Можно. А теперь прикиньте: не проще ли работать напрямую с таблицей? Определив заодно те display-поля, которые нужны впридачу? В целом согласен с Mazzy.
|
|
11.01.2007, 17:59 | #15 |
Участник
|
Пасиб за советы!
Тогда так: определю датасорсы, все...(это я уже сделал); список датасорсов(их имен) уже есть...осталось "выбрать" из них главного...думаю это не проблема... Выяснить где диспл. метод ,а где нет...вроде на этом форуме я где-то видел,..буду смотреть, разбираться... вопрос: как определить,...но на гриде есть столько то полей....и 2 из них диспленые... т.е как обратиться к контролу и спросить его... design("design").grid.stringedit ? ....как? |
|
11.01.2007, 18:10 | #16 |
Banned
|
Цитата:
http://www.axforum.info/forums/showthread.php?t=701 Последний раз редактировалось EVGL; 11.01.2007 в 18:17. |
|
04.09.2008, 19:06 | #17 |
Moderator
|
Некоторым боком сегодня был недалеко от этой темы и набросал небольшой пример. Немного помучался, куда помещать это сообщение - сюда или в свой "блог". Решил всё же сюда, так как здесь уже имеется интересное готовое обсуждение.
Простенький статический метод. Без больших претензий. Построчно выводит в буфер текстовые представления значений (valueStr) контролов грида (со строкой заголовков). Не умеет работать с выделенными строками, но учитывает сортировку, фильтрацию, перестановку и скрытие колонок пользователем. И нумерует строчки - о как! Может быть помещен, например, в Global или аналогичный класс - набор утилит (у меня такой класс называется KKu - я предпочитаю не портить фирменный Global ). X++: static TextBuffer gridToBuffer( FormRun _formRun, str _gridName, str _separator = '\t') { FormGridControl grid; FormControl control; FormDataSource formDataSource; Common common; int i; int row; str lineToBuffer; TextBuffer textBuffer = new TextBuffer(); ; grid = _formRun.design().controlName(_gridName); // заголовки колонок (label) -> вывод в буфер lineToBuffer = strfmt('%1%2', 'Row', _separator); for (i=1; i<=grid.controlCount(); i++) { control = grid.controlNum(i); if (control.isDisplayed()) { lineToBuffer += strFmt('%1%2', control.labelText(), _separator); } } lineToBuffer = subStr( lineToBuffer, 1, strLen(lineToBuffer)-strLen(_separator) ); textBuffer.appendText( lineToBuffer + '\n' ); // ищем датасорс грида for (i=1; i<=_formRun.dataSourceCount(); i++) { if (_formRun.dataSource(i).id() == grid.dataSource()) { formDataSource = _formRun.dataSource(i); break; } } // неявный цикл по строкам грида (явный - по датасорсу) row = 0; for ( common = formDataSource.getFirst() ? formDataSource.getFirst() : formDataSource.cursor(); common ; common = formDataSource.getNext() ) { row++; if (row==1) { formDataSource.first(); } else { formDataSource.next(); } // очередная строка -> вывод в буфер lineToBuffer = strFmt('%1%2', row, _separator); for (i=1; i<=grid.controlCount(); i++) { control = grid.controlNum(i); if (control.isDisplayed()) { lineToBuffer += strFmt('%1%2', strReplace(strReplace( control.valueStr(), '\n',' '), '\r',' '), _separator); } } lineToBuffer = subStr( lineToBuffer, 1, strLen(lineToBuffer)-strLen(_separator) ); textBuffer.appendText( lineToBuffer + '\n' ); } return textBuffer; } X++: public int mouseDblClick(int _x, int _y, int _button, boolean _Ctrl, boolean _Shift) { int ret; ret = super(_x, _y, _button, _Ctrl, _Shift); KKu::gridToBuffer(element, 'Grid').toClipboard(); return ret; } После двойного щелчка и наблюдения за тем, как пробежит вниз бегунок вертикальной полосы прокрутки, можно перейти в Excel и выполнить вставку. Если у вас очень много основных средств, желательно сначала наложить фильтр, чтобы в рамках эксперимента разумно ограничить количество строк в буфере. |
|
08.09.2009, 16:18 | #18 |
Axapta Retail User
|
Цитата:
Сообщение от Gustav
Простенький статический метод. Без больших претензий. Построчно выводит в буфер текстовые представления значений (valueStr) контролов грида (со строкой заголовков). Не умеет работать с выделенными строками, но учитывает сортировку, фильтрацию, перестановку и скрытие колонок пользователем. И нумерует строчки - о как! Может быть помещен, например, в Global или аналогичный класс - набор утилит (у меня такой класс называется KKu - я предпочитаю не портить фирменный Global ).
X++: static TextBuffer gridToBuffer( FormRun _formRun, str _gridName, str _separator = '\t') { FormGridControl grid; FormControl control; FormDataSource formDataSource; Common common; int i; int row; str lineToBuffer; TextBuffer textBuffer = new TextBuffer(); //+ для работы с FormGroupControl в гриде FormGroupControl groupCtrl; FormControl controlGrp; int j; //- для работы с FormGroupControl в гриде ; grid = _formRun.design().controlName(_gridName); // заголовки колонок (label) -> вывод в буфер lineToBuffer = strfmt('%1%2', 'Row', _separator); for (i=1; i<=grid.controlCount(); i++) { control = grid.controlNum(i); //+ для работы с FormGroupControl в гриде if(classIdGet(control) == classnum(FormGroupControl)) { groupCtrl = control; if(groupCtrl.isVisible()) { for(j=1; j<=groupCtrl.controlCount(); j++) { controlGrp = groupCtrl.controlNum(j); if (controlGrp.isDisplayed()) { lineToBuffer += strFmt('%1%2', controlGrp.labelText(), _separator); } } } } else //- для работы с FormGroupControl в гриде if (control.isDisplayed()) { lineToBuffer += strFmt('%1%2', control.labelText(), _separator); } } lineToBuffer = subStr( lineToBuffer, 1, strLen(lineToBuffer)-strLen(_separator) ); textBuffer.appendText( lineToBuffer + '\n' ); // ищем датасорс грида for (i=1; i<=_formRun.dataSourceCount(); i++) { if (_formRun.dataSource(i).id() == grid.dataSource()) { formDataSource = _formRun.dataSource(i); break; } } // неявный цикл по строкам грида (явный - по датасорсу) row = 0; for ( common = formDataSource.getFirst() ? formDataSource.getFirst() : formDataSource.cursor(); common ; common = formDataSource.getNext() ) { row++; if (row==1) { formDataSource.first(); } else { formDataSource.next(); } // очередная строка -> вывод в буфер lineToBuffer = strFmt('%1%2', row, _separator); for (i=1; i<=grid.controlCount(); i++) { control = grid.controlNum(i); //+ для работы с FormGroupControl в гриде if(classIdGet(control) == classnum(FormGroupControl)) { groupCtrl = control; if(groupCtrl.isVisible()) { for(j=1; j<=groupCtrl.controlCount(); j++) { controlGrp = groupCtrl.controlNum(j); if (controlGrp.isDisplayed()) { lineToBuffer += strFmt('%1%2', strReplace(strReplace( controlGrp.valueStr(), '\n',' '), '\r',' '), _separator); } } } } else //- для работы с FormGroupControl в гриде if (control.isDisplayed()) { lineToBuffer += strFmt('%1%2', strReplace(strReplace( control.valueStr(), '\n',' '), '\r',' '), _separator); } } lineToBuffer = subStr( lineToBuffer, 1, strLen(lineToBuffer)-strLen(_separator) ); textBuffer.appendText( lineToBuffer + '\n' ); } return textBuffer; } |
|
|
За это сообщение автора поблагодарили: Gustav (7). |
09.09.2009, 14:21 | #19 |
Участник
|
Вообще, интересно было бы узнать, что топикстартер хочет "замутить"? И что за форма, своя собственная, или уже кем-то сделанная? Почему нужны данные с грида, а не из таблицы, данные которой отображает грид?
Возможно, вам помогут в этом классы xFormTree или CCFormTreeDatasource (от этого класса лучше сделать наследника).
__________________
// no comments Последний раз редактировалось dech; 09.09.2009 в 14:24. |
|