|
24.03.2008, 19:43 | #1 |
Moderator
|
Макс, большое спасибо за наводку! Уже нашёл очень полезную ветку: Функция, которая убирает перевод каретки в строке. и пошёл читать справку к функции match про регулярные выражения.
"Хорошо! "Стамбул - город контрастов". А объявление перепишем:" (с) X++: static str trimLikeExcel(str _sourceString) { TextBuffer buf = new TextBuffer(); ; buf.setText(_sourceString); buf.replace(' +', ' '); return strLRTrim(buf.getText()); } |
|
24.03.2008, 22:24 | #2 |
Участник
|
|
|
27.06.2008, 13:08 | #3 |
Moderator
|
Подручные средства для облегчения создания рутинных фрагментов кода
Во загнул, скажете, но на самом деле все очень просто. То тут, то там приходится выписывать последовательности операторов присваивания для перевалки данных из одного места в другое, например, пересылать значения из несвязанных контролов формы в поля таблицы. Для оформления подобных операций желательно иметь выстроенный список полей с одной и с другой стороны, которые в коде необходимо "совместить" друг с другом посредством знака равенства.
Такое совмещение можно приготовить в любом редакторе текста, позволяющем блочные вставки, например, в MultiEdit или в текстовом редакторе программы FAR (выделение прямоугольника при помощи Alt+стрелка), и затем вставить в текст конкретного метода в Axapta. Еще проще подготовить присваивания при помощи таблиц Excel, вставив наборы полей в соседние колонки, связав их формулами и наконец скопировав вычисленные значения формул в код X++. Пусть, например, имееется набор полей таблицы: Table1.StrField1 Table1.StrField2 Table1.StrField3 и набор контролов формы (подразумевается AutoDeclaration = Yes): StringEditControl1 StringEditControl2 StringEditControl3 Допустим, что код должен выглядеть следующим образом: Table1.Field1 = StringEditControl1.valueStr(); Table1.Field2 = StringEditControl2.valueStr(); Table1.Field3 = StringEditControl3.valueStr(); Создадим эти операторы присваивания при помощи Excel. Для этого: - скопируем набор полей в столбец A Excel, начиная с ячейки A1; - скопируем набор контролов в столбец B Excel, начиная с ячейки B1; - в ячейку C1 введем формулу: =A1 & " = " & B1 & ".valueStr();" и распространим ее вниз копированием на все необходимые строки; - далее из столбца C забираем строки кода X++ для вставки в Axapta. Всё неплохо. Дело осталось за малым - автоматизировать получение самих списков полей (не вручную их же набирать в самом деле! ). Вот два коротеньких джобика, которые могут помочь в этом. Первый - получение списка полей таблицы: X++: static void Job_getTableFieldList(Args _args) { str tableName = 'RAssetTable'; // подставь здесь свою таблицу treeNode treeNode = new xInfo() .rootNode() .AOTfindChild('Data Dictionary') .AOTfindChild('Tables') .AOTfindChild( tableName ) .AOTfindChild('Fields'); ; treeNode = treeNode.AOTfirstChild(); while ( treeNode ) { info( strfmt('%1.%2', tableName, treeNode.treeNodeName()) ); treeNode = treeNode.AOTnextSibling(); } } Второй джоб - получение списка контролов формы: X++: static void Job_getFormControlList(Args _args) { str formName = 'RAssetTable'; // подставь здесь свою форму int row, hLevel; // служебные поля на случай вывода сквозной нумерации строк или уровней иерархии TreeNode treeNode = new xInfo() .rootNode() .AOTfindChild('Forms') .AOTfindChild( formName ) .AOTfindChild('Designs') .AOTfindChild('Design'); str controlType; str controlName; void nextNode( treeNode _tn) { ; hLevel++; _tn = _tn.AOTfirstChild(); while (_tn ) { if (strscan(_tn.treeNodeName(), ':', 1, 10000)) { row++; [controlType, controlName] = str2con(_tn.treeNodeName(), ':'); if (substr(controlType,1,1)=='[') // Tab, TabPage, Group, Grid, ButtonGroup { controlType = substr(controlType, 2, strlen(controlType) ); controlName = substr(controlName, 1, strlen(controlName)-1); } info( strfmt('%1.valueStr();', controlName) ); } nextNode(_tn ); _tn = _tn.AOTnextSibling(); } hLevel--; } ; nextNode( treeNode ); } |
|
09.09.2008, 11:40 | #4 |
Участник
|
В версии 4.0 получение списка полей таблицы есть в стандартной функциональности.
- В форме с нужной записью, заходим в паспорт записи (правый клик/ паспорт записи). - нажимаем кнопку Сценарий. Остается только вставить текст в нужное место. 2Gustav При вставке получаем следующий код: X++: CustTable.AccountNum = "000001_039"; CustTable.Name = "ООО """; CustTable.Address = "180000, Светлово, ул. Пермяковская, д.21"; CustTable.Phone = "45254565"; CustTable.TeleFax = ""; CustTable.InvoiceAccount = ""; ... CustTable.MultiDiscPct = 0.00; CustTable.EndDiscPct = 0.00; CustTable.RContractDimension = NoYes::Yes; CustTable.insert(); Последний раз редактировалось AlGol; 22.09.2008 в 11:40. |
|
|
За это сообщение автора поблагодарили: Lemming (1), Gustav (3). |
06.10.2008, 17:01 | #5 |
Moderator
|
Визуальная имитация раннего связывания COM-объектов
Известно, что с COM-объектами Аксапта работает через позднее связывание. Это означает, что при портировании в Х++, например, кода VBA из Excel, нам придется расписать отдельными операторами X++ все точки, разделяющие объекты в операторах VBA.
Допустим, у нас есть такой код VBA, созданный макрорекордером и нами слегка подправленный, который в Excel записывает значение 123 в ячейку C2 активного листа активной книги, затем делает шрифт этой ячейки жирным ("болдит") и, наконец, заливает ячейку светложелтым цветом: Код: Sub Macro1() Range("C2").FormulaR1C1 = "123" Range("C2").Font.Bold = True Range("C2").Interior.ColorIndex = 36 'Light Yellow End Sub X++: { COM application; COM workbook = SysExcelApplication::construct().workbooks().add().comObject(); COM range; COM font; COM interior; ; application = workbook.Parent(); application.Visible(true); range = application.Range('C2'); range.FormulaR1C1(123); font = range.Font(); font.Bold(true); interior = range.Interior(); interior.ColorIndex(36); } Вместо нескольких таких переменных, истинный объектный смысл каждой из которых нас в данном случае мало интересует, можно использовать одну фиктивную. Обычно я называю ее comTemp - для акцентирования ее "временности" и "промежуточности". С такой "болван"-переменной можно написать операции следующим образом: X++: COM comTemp;
..........
comTemp = range.Font();
comTemp . Bold(true);
comTemp = range.Interior();
comTemp . ColorIndex(36); X++: COM::createFromObject( range.Font()).Bold( true );
COM::createFromObject( range.Interior()).ColorIndex(36); Таким образом, для реализации следующего "многоточечного" оператора VBA: Код: Application.ActiveWorkbook.Worksheets.Item(1).Cells.Item(2,3).Font.Bold = True X++: comTemp = application.ActiveWorkbook();
comTemp = comTemp.Worksheets();
comTemp = comTemp.Item(1);
comTemp = comTemp.Cells();
comTemp = COM::createFromVariant(comTemp.Item(2,3));
comTemp = comTemp.Font();
comTemp.Bold(true); В целях "борьбы" с описанным явлением я наваял совсем небольшой метод, с использованием функции runbuf, который позволяет существенно сократить количество строк код и придать вызову внешнюю похожесть на оператор VBA: X++: { COM application; COM workbook = SysExcelApplication::construct().workbooks().add().comObject(); COM range; COM comTemp; ; application = workbook.Parent(); application.Visible(true); range = application.Range('C2'); range.FormulaR1C1(123); comTemp = comEarlyBindingImitation( application, 'ActiveWorkbook()','Worksheets()','Item(1)','Cells()','~Item(2,3)','Font()'); comTemp.Bold(true); } X++: static COM comEarlyBindingImitation( COM _com0, str _com1 = '', str _com2 = '', str _com3 = '', str _com4 = '', str _com5 = '', str _com6 = '', str _com7 = '', str _com8 = '') { str myjob; str getSourcePart(str _com = '') { if (_com) if (subStr(_com,1,1) != '~') return strFmt('c=c.%1; ', _com); else return strFmt('c=COM::createFromVariant(c.%1); ', subStr(_com,2,strLen(_com)-1)); else return ''; } ; myjob = 'COM comEaBIm(COM _com0) {COM c;; c = _com0; '; myjob += getSourcePart(_com1); myjob += getSourcePart(_com2); myjob += getSourcePart(_com3); myjob += getSourcePart(_com4); myjob += getSourcePart(_com5); myjob += getSourcePart(_com6); myjob += getSourcePart(_com7); myjob += getSourcePart(_com8); myjob += 'return c; }'; return runbuf(myjob, _com0); } Интересно, что терминальные свойства (типа Bold или ColorIndex) можно тоже включить в это "раннее связывание" и тогда вообще обойтись одним оператором для одной операции. Следующие два оператора работают как надо: X++: comEarlyBindingImitation(application, 'Range("C2")','Font()','Bold(true)'); comEarlyBindingImitation(application, 'Range("C2")','Interior()','ColorIndex(36)'); |
|
|
За это сообщение автора поблагодарили: kashperuk (3), aidsua (1). |
Теги |
excel, rls, полезное, blog, axapta |
|
|