Цитата:
Сообщение от
decoder
Ок. Вот я как раз и не понимаю, как этот супермакрос

будет выглядеть в Х++...

Примерно так:
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
И это нормально работает в Excel. А теперь попробуйте задать этот Zoom из Аксапты - оператор pageSetup.Zoom(false); вызовет ошибку... Думаем, что делать дальше...
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})');
Остается вопрос с языком формул, разделителем списка Excel и разделителем колонок массива. Как видно, у меня язык формул английский, а оба разделителя - точка с запятой. У кого-то сработает с запятой, у кого-то с русскими буквами (щас вспомню как по-русски называется этот оператор... ПАРАМЕТРЫ.СТРАНИЦЫ - кто б сомневался

)
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();
}
Если задать обе переменные fitToPagesWide и fitToPagesTall равными 0, то соответствующие поля "Fit to" в диалоге "Page Setup" будут пустыми и выделенной станет верхняя опция "Adjust to ... % normal size".
Для исполнения джоба выше нужны некоторые методы из моего сборника статических методов - класса 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();
// если была создана отдельная кратковременная, то она автоматически закроется
}
Уфф... Всё! Поехал домой болеть за ЦСКА против Бешикташа