|
![]() |
#1 |
Участник
|
запишите макрос в Excel, нужные свойства вроде FitToPagesWide и FitToPagesTall
|
|
![]() |
#2 |
Участник
|
Ок. Вот я как раз и не понимаю, как этот супермакрос
![]() ![]() |
|
![]() |
#3 |
Moderator
|
Цитата:
X++: #define.xlDialogPageSetup(7) static void Job210_ExcelFitToPagesDemo(Args _args) { ComExcelDocument_RU excel = new ComExcelDocument_RU(); COM doc; COM app; COM worksheet; COM pageSetup; COM temp; ; excel.newFile(); doc = Excel.getComDocument(); app = doc.Application(); worksheet = app.ActiveSheet(); pageSetup = worksheet.PageSetup(); pageSetup.FitToPagesWide(2); pageSetup.FitToPagesTall(3); // это для демонстрации того, что получается temp = app.Dialogs(); temp = temp.Item(#xlDialogPageSetup); temp.Show(); } ![]() P.S. Коллеги забыли про еще один оператор VBA. Полный фрагмент на VBA должен выглядеть так: Код: With ActiveSheet.PageSetup .Zoom = False .FitToPagesWide = 2 .FitToPagesTall = 3 End With P.P.S. Нашёл пилюлю вот здесь: http://www.ozgrid.com/forum/showthread.php?t=49644 Вместо трёх операторов делаем один: X++: //// pageSetup.Zoom(false); // и так не работающий // pageSetup.FitToPagesWide(2); // pageSetup.FitToPagesTall(3); app.ExecuteExcel4Macro('PAGE.SETUP(;;;;;;;;;;;;{2;3})'); ![]() P.P.P.S. Вот как-то так вырисовывается пример в окончательном виде с учетом всех известных на данный момент особенностей региональных настроек Excel: X++: #define.xlDialogPageSetup(7) static void Job210_ExcelFitToPagesDemo(Args _args) { ComExcelDocument_RU excel = new ComExcelDocument_RU(); COM doc; COM app; COM temp; str macroFormula; str xlListSep = KKu::excelListSeparator(app); str xlColSep = KKu::excelColumnSeparator(app); str xlForLang = KKu::excelFormulaLanguage(app); int fitToPagesWide = 0; // страниц в ширину int fitToPagesTall = 10; // страниц в высоту ; excel.newFile(); doc = excel.getComDocument(); app = doc.Application(); xlListSep = KKu::excelListSeparator(app); xlColSep = KKu::excelColumnSeparator(app); xlForLang = KKu::excelFormulaLanguage(app); macroFormula = strFmt('%1(%2{%3%4%5})', xlForLang=='English'?'PAGE.SETUP':'ПАРАМЕТРЫ.СТРАНИЦЫ', strRep(xlListSep,12), fitToPagesWide ? int2str(fitToPagesWide) : (xlForLang=='English'?'#N/A':'#Н/Д'), xlColSep, fitToPagesTall ? int2str(fitToPagesTall) : (xlForLang=='English'?'#N/A':'#Н/Д')); app.ExecuteExcel4Macro(macroFormula); // для активного в данный момент листа // это для демонстрации того, что получается temp = app.Dialogs(); temp = temp.Item(#xlDialogPageSetup); temp.Show(); } Для исполнения джоба выше нужны некоторые методы из моего сборника статических методов - класса KKu (мой персональный "Global"). Вот они: X++: // определение разделителя колонок Excel - для FormulaArray static str excelColumnSeparator(COM _excelApplication = null) { #define.xlColumnSeparator(14) ; return KKu::excelSeparator(#xlColumnSeparator, _excelApplication); } // Определение языка формул Excel для свойства Range.Formula // (именно Formula, а не FormulaLocal !!!) // подробности см. здесь: // [url=http://www.axforum.info/forums/showthread.php?p=195646#post195646]Строка в Excel[/url] // СПОСОБ: // помещаем в "международное" свойство формулу на русском языке // и проверяем последующую реакцию Excel // по окончании проверки удаляем временные объекты static str excelFormulaLanguage(COM _excelApplication = null) { str ret; COM workbook; COM range; COMVariant rangeText; boolean separateSession = false; ; // если сессия не передается параметром... if (! _excelApplication) { // ...то пробуем прицепиться к существующей _excelApplication = COM::getObject('Excel.Application'); // если существующей тоже нет... if (! _excelApplication) { // то создаем отдельную - кратковременную - только лишь для определения языка _excelApplication = new COM('Excel.Application'); separateSession = true; } } workbook = _excelApplication.Workbooks(); workbook = workbook.Add(); range = _excelApplication.Range('A1'); // помещаем в "международное" свойство формулу на русском языке // и проверяем последующую реакцию Excel range.NumberFormat('0'); // на всякий случай range.Formula('=СУММ(1+1)'); range.Calculate(); // на всякий случай rangeText = range.Text(); if (rangeText.bStr()=='2') // здесь ожидаются значения: #NAME? или #ИМЯ? или 2 ret = 'Russian'; else ret = 'English'; workbook.Close(false); if (separateSession) _excelApplication.Quit(); return ret; } // определение разделителя списка Excel // нужно для диапазонов вида Range('C:C,F:F') // можно передать Excel берем параметром из контекста задачи, // чтобы не загружать отдельную сессию из-за единственного символа; // а можно и не загружать static str excelListSeparator(COM _excelApplication = null) { #define.xlListSeparator(5) ; return KKu::excelSeparator(#xlListSeparator, _excelApplication); } // Created on 04 Авг 2009 at 16:04:57 by KKU // поскольку уже нужно как минмиум два разделителя для Excel: списка и колонок, то делаем для них общее ядро static str excelSeparator(int _separator, COM _excelApplication = null) { SysExcelApplication xlApp; COMVariant sep; ; // если сессия не передается параметром... if (! _excelApplication) { // ...то пробуем прицепиться к существующей _excelApplication = COM::getObject('Excel.Application'); // если существующей тоже нет... if (! _excelApplication) { // то создаем отдельную - кратковременную - только лишь для определения разделителя xlApp = SysExcelApplication::construct(); _excelApplication = xlApp.comObject(); } } sep = _excelApplication.International(_separator); return sep.bStr(); // если была создана отдельная кратковременная, то она автоматически закроется } ![]() Последний раз редактировалось Gustav; 30.09.2009 в 19:31. |
|
![]() |
#4 |
Moderator
|
ХА-ХА-ХАААА... А вообще всё было проще!
![]() ![]() COMVariant для Zoom!! X++: #define.xlDialogPageSetup(7) static void Job211(Args _args) { ComExcelDocument_RU excel = new ComExcelDocument_RU(); COM doc; COM app; COM worksheet; COM pageSetup; COM temp; COMVariant cv = new COMVariant(); ; excel.newFile(); doc = Excel.getComDocument(); app = doc.Application(); worksheet = app.ActiveSheet(); pageSetup = worksheet.PageSetup(); cv.boolean(false); pageSetup.Zoom(cv); pageSetup.FitToPagesWide(2); pageSetup.FitToPagesTall(3); // это для демонстрации того, что получается temp = app.Dialogs(); temp = temp.Item(#xlDialogPageSetup); temp.Show(); } Последний раз редактировалось Gustav; 30.09.2009 в 20:14. |
|
|
За это сообщение автора поблагодарили: Alenka (1), zelibobis (1), decoder (1). |
![]() |
#5 |
Moderator
|
Ну типа, ага. Между прочим, какое-то Ваше же сообщение и вспомнил на эту тему
![]() Владимир, а не посмотрите еще одну затыку: Цитата:
P.S. Хотя я, наверное, допёр... Надо было внимательно читать собственную ссылку: Цитата:
Сообщение от Gustav
![]() Нашёл пилюлю вот здесь: http://www.ozgrid.com/forum/showthread.php?t=49644
X++: int fitToPagesWide = 10; COMVariant cvWide = new COMVariant(); if (fitToPagesWide) cvWide.int( fitToPagesWide ); else cvWide.boolean( false ); pageSetup.FitToPagesWide(cvWide); Последний раз редактировалось Gustav; 30.09.2009 в 23:54. |
|
![]() |
#6 |
Moderator
|
Проверил, работает. Выстрадался окончательный вариант:
X++: #define.xlDialogPageSetup(7) static void Job212(Args _args) { ComExcelDocument_RU excel = new ComExcelDocument_RU(); COM doc; COM app; COM worksheet; COM pageSetup; COM temp; int fitToPagesWide = 5; // страниц в ширину int fitToPagesTall = 0; // страниц в высоту, если 0, то поле пустое COMVariant cvZoom = COMVariant::createFromBoolean(false); COMVariant cvWide = fitToPagesWide ? COMVariant::createFromInt( fitToPagesWide ) : COMVariant::createFromBoolean( false ); COMVariant cvTall = fitToPagesTall ? COMVariant::createFromInt( fitToPagesTall ) : COMVariant::createFromBoolean( false ) ; ; excel.newFile(); doc = excel.getComDocument(); app = doc.Application(); worksheet = app.ActiveSheet(); pageSetup = worksheet.PageSetup(); pageSetup.Zoom(cvZoom); pageSetup.FitToPagesWide(cvWide); pageSetup.FitToPagesTall(cvTall); // это для демонстрации того, что получается temp = app.Dialogs(); temp = temp.Item(#xlDialogPageSetup); temp.Show(); } |
|
![]() |
#7 |
Moderator
|
И всё-таки сгодится в хозяйстве макро PAGE.SETUP
Я еще раз внимательно изучил ссылку-пилюлю: http://www.ozgrid.com/forum/showthread.php?t=49644.
Человеку, который там задает вопрос, нужно было следующее: прочитать значение процентов масштабирования после того, как ранее была применена подгонка по страницам (Fit to). Когда это делается вручную, то сначала устанавливаются значения Fit to и жмётся OK. Рабочий лист при этом должен быть с большим количеством данных, иначе эффекта масштабирования не будет - пустой лист не масштабируется. Далее повторно вызываем диалог "Page Setup" и видим, что в поле "Adjust to...% normal size" отображается конкретный процент масштабирования, который автоматически рассчитался в Excel по нашем параметрам подгонки. И пусть это значение нам и нужно получить в коде. Отвечающий на вопрос там предлагает дважды выполнить команду PAGE.SETUP. Но мы-то вроде умеем уже и без нее устанавливать необходимые свойства. Правда, оказывается, что этого недостаточно для получения значения Zoom'а... Не буду вдаваться в подробности, а просто приведу джоб в окончательном виде, когда мне удалось прочитать значение процентов масштабирования после подгонки, и вы сами всё увидите: X++: static void Job212_PageSetupReadPercent(Args _args) { ComExcelDocument_RU excel = new ComExcelDocument_RU(); COM doc; COM app; COM worksheet; COM pageSetup; COM temp; COM range; str macroFormula; str xlForLang = KKu::excelFormulaLanguage(app); int fitToPagesWide = 0; int fitToPagesTall = 5; COMVariant cvZoom = COMVariant::createFromBoolean(false); COMVariant cvZoomNum; COMVariant cvWide = fitToPagesWide ? COMVariant::createFromInt( fitToPagesWide ) : COMVariant::createFromBoolean( false ); COMVariant cvTall = fitToPagesTall ? COMVariant::createFromInt( fitToPagesTall ) : COMVariant::createFromBoolean( false ) ; void executePageSetup() { // даже "холостой" вызов PAGE.SETUP (т.е. без параметров) // как бы является нажатием кнопки ОК в диалоге "Page Setup" macroFormula = strFmt('%1()', xlForLang=='English'?'PAGE.SETUP':'ПАРАМЕТРЫ.СТРАНИЦЫ'); app.ExecuteExcel4Macro(macroFormula); } ; excel.newFile(); doc = excel.getComDocument(); app = doc.Application(); // заполняем лист большим количеством данных worksheet = app.ActiveSheet(); range = worksheet.Range('A1:Z1000'); range.Value2('test'); pageSetup = worksheet.PageSetup(); pageSetup.Zoom(cvZoom); pageSetup.FitToPagesWide(cvWide); pageSetup.FitToPagesTall(cvTall); // сравните с иным конечным видом диалога "Page Setup, // закомментировав следующую строку executePageSetup(); pageSetup.FitToPagesWide(cvZoom); // cvZoom здесь используется pageSetup.FitToPagesTall(cvZoom); // как носитель значения false // сравните с иным конечным видом диалога "Page Setup, // закомментировав следующую строку executePageSetup(); // читаем значение процентов масштабирования cvZoomNum = pageSetup.Zoom(); box::info(strFmt('Adjust to %1 % normal size', cvZoomNum.long())); // это для демонстрации того, что получается temp = app.Dialogs(); temp = temp.Item(#xlDialogPageSetup); temp.Show(); } После запуска этого же джоба с закомментированными строками executePageSetup (см. в комментариях, где я прошу это сделать) картинки будут менее радостными: Вот как-то так... Уфф... И приятно, что ЦСКА вчера не посрамил Страну и выиграл 2:1 ![]() |
|
Теги |
excel, масштаб, программно, com-объект |
|
Опции темы | Поиск в этой теме |
Опции просмотра | |
|