22.03.2019, 17:03 | #1 |
Участник
|
Как это работает через NET?
В свое время была тема "Как программно из AX присвоить bookmark в Excel"
Как программно из AX присвоить bookmark в Excel Там это делалось через COM, и все было хорошо. Пытаюсь сделать через NET? - не ругается, но и не создает. Microsoft.Office.Interop.Excel.WorksheetClass netObject = range.worksheet().netObject(); Microsoft.Office.Interop.Excel.Names netNames = netObject.get_Names(); ; ...... netNames.Add("SSSS", "=$A$1" ,null ,null ,null ,null ,null ,null ,null ,null ,null ); ..... |
|
28.03.2019, 11:31 | #2 |
Участник
|
Добрый день.
В рамках Аксапты, видимо, нужно передавать аргументы. https://docs.microsoft.com/en-us/dot...view=excel-pia |
|
29.03.2019, 16:13 | #3 |
Участник
|
Добрый день, Товарищ ♂uatr!
Это я читал, а в коде будет выглядеть передача необязательных аргументов со значениями по умолчанию, а то не указывать их нельзя, а в указанном варианте - см. выше. |
|
29.03.2019, 16:40 | #4 |
Участник
|
попробуйте вместо null передавать результат вот этого метода:
X++: protected final CLRObject getClrMissingArg() { CLRObject clrMissingArg; // что передавать вместо необязательных параметров System.Reflection.FieldInfo fieldInfo; System.Type type; #define.SystemReflectionMissing ('System.Reflection.Missing') ; // if (!isMissingArgInited) { // BP deviation documented type = System.Type::GetType( #SystemReflectionMissing ); fieldInfo = type.GetField( @"Value" ); clrMissingArg = fieldInfo.GetValue( null ); // isMissingArgInited = true; } return clrMissingArg; } |
|
29.03.2019, 17:40 | #5 |
Участник
|
Увы, Logger, благодарю, но не прокатило. Ругается на неинициализированность объекта CLRObject, хотя метод возвращает его "живым". Вы сами пробовали прогнать этот пример (у меня AX 4.0)? Может на другой версии это рабочее.
|
|
30.03.2019, 10:14 | #6 |
Участник
|
|
|
31.03.2019, 02:54 | #7 |
Участник
|
Сам пример в С#/.Net (i.e. Console App) пробовали запустить? Работает?
__________________
AxAssist 2012 - Productivity Tool for Dynamics AX 2012/2009/4.0/3.0 |
|
02.04.2019, 18:29 | #8 |
Участник
|
to Alex_KD
Вполне себе Microsoft.Office.Interop.Excel.Application ObjExcel = new Microsoft.Office.Interop.Excel.Application(); Microsoft.Office.Interop.Excel.Workbook workBook = ObjExcel.Workbooks.Add(Type.Missing); Microsoft.Office.Interop.Excel.Worksheet sheet = ObjExcel.Worksheets.get_Item(1); Microsoft.Office.Interop.Excel.Names netNames = workBook.Names; netNames.Add("SSSS", "=$A$1"); ObjExcel.Visible = true; P.S. Что интересно,NET, как и COM ActiveWorkbook.Names("sssss").Delete не видят. |
|
06.05.2019, 15:55 | #9 |
Участник
|
подключите dll EPPlus - достойная замена .NET-способу.
Можно строить таблицы в пакетном режиме, но и на клиенте скорость тоже бешеная. Плюс можно использовать темплейты с заготовленными пивотами и т.д. Пример с коментарием: X++: OfficeOpenXml.ExcelPackage excelPackage = new OfficeOpenXml.ExcelPackage(); OfficeOpenXml.ExcelWorkbook excelWorkbook = excelPkg.get_Workbook(); OfficeOpenXml.ExcelWorksheets excelWorksheets = excelWorkbook.get_Worksheets(); OfficeOpenXml.ExcelWorksheet excelWorksheet = excelWorksheets.get_Item("Sheet1"); OfficeOpenXml.ExcelRange excelRange = excelWorksheet.get_Cells(); excelRange.get_Item('A1').AddComment("qqq","ag"); |
|
07.05.2019, 18:55 | #10 |
Участник
|
to AnGor За информацию - спасибо, буду иметь ввиду. Только здесь решалась не просто задача на быстрый вывод в excel. Хотелось следующее. Есть темплейт xltx. На листе - некая область (колонки, табличная часть, подвал). По логике отчета эта область размножается/ копируется с последующей вставкой данных, условно, по разным подразделениям, число которых заранее не известно. Чтобы не париться с подсчетами количества строк, реализовывалась идея создать нужное число именованных Range, ориентируясь на которые скопировать образец с форматированием и вставлять соответствующие данные, используя только относительные смещения (абсолютные координаты знает конкретный Range, а я их знать не хочу).
Задачу решил, обойдя NET по периметру. Именованные Range скопировал еще при подготовке шаблона (job через COM), взяв их число с запасом. При формировании отчета (я привязан к NET) просто вставляю данные в нужный Range, получив его имя по номеру. Работает. Удобно. Легко сопровождаемо и наращиваемо. Просто жаль, что такой удобный механизм, как именованный Range приходится использовать…через подобную проктологию. |
|
09.05.2019, 10:37 | #11 |
Участник
|
Пару месяцев нвзад была очень похожая задача - один в один без подвалов, но с разрывами страниц.
С первой по третью строку шапка, 4 и 5 - строка Итоговый вид так я множу шапку: X++: public boolean pasteRepHeader(OfficeOpenXml.ExcelWorksheet _ExcelWorksheet, int _row) { #define.RepHeader('RepHeader') #define.tmp('tmp') OfficeOpenXml.ExcelWorksheet fromExcelWorksheet; OfficeOpenXml.ExcelRange fromExcelRange; OfficeOpenXml.ExcelRange toExcelRange; boolean ret = true; fromExcelWorksheet = excelEPPLus.getWorksheet(#tmp); fromExcelRange = fromExcelWorksheet.get_Cells(); toExcelRange = _ExcelWorksheet.get_Cells(); fromExcelRange = fromExcelRange.get_Item(1,1,3,11); toExcelRange = toExcelRange.get_Item(_row,1,_row+3,11); fromExcelRange.Copy(toExcelRange); return ret; } X++: public boolean pasteRepLine(OfficeOpenXml.ExcelWorksheet _ExcelWorksheet, int _row) { #define.tmp('tmp') OfficeOpenXml.ExcelWorksheet fromExcelWorksheet; OfficeOpenXml.ExcelRange fromExcelRange; OfficeOpenXml.ExcelRange toExcelRange; boolean ret = true; fromExcelWorksheet = excelEPPLus.getWorksheet(#tmp); fromExcelRange = fromExcelWorksheet.get_Cells(); toExcelRange = _ExcelWorksheet.get_Cells(); fromExcelRange = fromExcelRange.get_Item(4,1,5,11); toExcelRange = toExcelRange.get_Item(_row,1,_row+1,11); fromExcelRange.Copy(toExcelRange); return ret; } X++: ...
excelColumn = ExcelWorksheet.Column(_col);
excelColumn.set_PageBreak(true);
... |
|