Цитата:
Изначально опубликовано Alks
Вчера вот записывал макросы установки типа ячейки - в VB код для ячейки генерится с NumberFormat = "#,##0.00", а в X++ NumberFormat("#,##0.00") ругается "не могу мол установить такой бредовый формат ячейки. Путём проб и ошибок выяснилось что на самом деле надо использовать маску поля "# ##0,00".
Проблема в том, что Excel использует
текущие региональные настройки системы (Windows). А на разных машинах, соответственно, могут быть разные настройки для символов разделителей целой и дробной части и для символов разделителей троек чисел.
Чтобы определить, какой же именно символ используется я написал в классе ComExcelDocument_RU такой метод
PHP код:
// Возвращает указанную региональную настройку
// Поскольку различные региональные настройки имеют разный тип, то используется контейнер из одного элемента
// Возвожные значения параметра параметра смотри в справке по Visual Basic в Excel на свойство International
// Наиболее нужные
/*
xlDecimalSeparator = 3 - символ разделитель целой и дробной части
xlThousandsSeparator = 4 - символ разделитель троек цифр
xlDateSeparator = 17 - символ разделитель в датах
xlTimeSeparator = 18 - символ разделитель часов и минут
xlGeneralFormatName = 26 - строка имени основного формата данных (обычно General)
xl24HourClock = 33 - true - если часы отображаются в 24 часовом формате, false - если в 12 часовом
xl4DigitYears = 43 - true - если отображаются 4 знака года, false - если 2
xlDateOrder = 32 - как отображается дата: 0 - месяц/день/год, 1 - день/месяц/год, 2 - год/месяц/день
*/
container International(int _international)
{
COMVariant comInternational;
container con = connull();
;
if (m_comApplication)
{
try
{
comInternational = m_comApplication.International(_international);
switch (comInternational.variantType())
{
case COMVariantType::VT_BOOL:
{
con = conIns(con,1,comInternational.boolean());
break;
}
case COMVariantType::VT_BSTR:
{
con = conIns(con,1,comInternational.bStr());
break;
}
case COMVariantType::VT_DATE:
{
con = conIns(con,1,comInternational.date());
break;
}
case COMVariantType::VT_DECIMAL:
{
con = conIns(con,1,comInternational.decimal());
break;
}
case COMVariantType::VT_INT:
{
con = conIns(con,1,comInternational.int());
break;
}
}
}
catch (Exception::Error || Exception::Internal)
{
throw error("Ошибка в функции " + funcname());
}
}
return con;
}
Пример использования:
PHP код:
static void JOB_Excel_International(Args _args)
{
COMExcelDocument_RU excel;
COM comRange;
str strPoint, // Символ разделитель целой и дробной части в Excel
strSeparator; // Символ разделитель тысяч
;
#define.xlDecimalSeparator(3)
#define.xlThousandsSeparator(4)
excel = new ComExcelDocument_RU();
// Создаю чистый лист Excel
excel.newFile('',true);
excel.visible(true);
strPoint = conpeek(excel.rtg_International(#xlDecimalSeparator),1);
strSeparator = conpeek(excel.rtg_International(#xlThousandsSeparator),1);
// Форматирую весь столбец А
comRange = excel.findRange('A:A');
comRange.numberFormat("#"+strSeparator+"##0"+strPoint+"00");
excel.insertValue('A1',123456.78);
return;
}
Здесь я несколько сжульничал, поскольку метод ComExcelDocument_RU.findRange() имеет область видимости protected. Т.е. таким образом его вызвать нельзя, если не изменить область видимости на public. Но, идея, думаю, понятна.
Есть еще один "фокус". Если использовать для вставки в Excel не напрямую числа, а преобразовав его через strFmt(), то региональные настройки будут использованы автоматически без предварительного форматирования ячеек:
excel.insertValue('A1',strFmt('%1',123456.78));