Цитата:
Сообщение от
Gustav
Что если попробовать нарезать ваши 500 серийников на 10 колонок по 60, а в 11-й собрать при помощи формулы?
Вот, воплотил идею в примере. По окончании работы в ячейках K1 и K2 (11-я колонка) - честные строки из 600 серийников (9000 символов).
X++:
static void Job148(Args _args)
{
COM rstAxa;
COM flds, fld;
COM xlApp;
COM wbks, wbk;
COM wkss, wks;
COM rng;
str strValue;
str strFormula;
COMVariant sep;
#define.xlPasteValues(-4163)
#define.xlListSeparator(5)
int adoTypeToExcel(str _type)
{
switch (_type)
{
case 'num' : return 5; // adDouble
case 'str' : return 8; // adBSTR
case 'date': return 133; // adDBDate
}
return 8;
}
;
rstAxa = new COM('ADODB.Recordset');
flds = rstAxa.Fields();
flds.Append('str1' , adoTypeToExcel('str' ));
flds.Append('str2' , adoTypeToExcel('str' ));
flds.Append('str3' , adoTypeToExcel('str' ));
flds.Append('str4' , adoTypeToExcel('str' ));
flds.Append('str5' , adoTypeToExcel('str' ));
flds.Append('str6' , adoTypeToExcel('str' ));
flds.Append('str7' , adoTypeToExcel('str' ));
flds.Append('str8' , adoTypeToExcel('str' ));
flds.Append('str9' , adoTypeToExcel('str' ));
flds.Append('str10', adoTypeToExcel('str' ));
flds.Append('str11', adoTypeToExcel('str' ));
rstAxa.Open();
xlApp = new COM('Excel.Application');
// создаем формулу с правильным разделителем списка (запятой или точкой с запятой)
sep = xlApp.International(#xlListSeparator);
strFormula = strFmt('=CONCATENATE(RC[-10]%1RC[-9]%1RC[-8]%1RC[-7]%1RC[-6]%1RC[-5]%1RC[-4]%1RC[-3]%1RC[-2]%1RC[-1])',
sep.bStr());
strValue = strRep('1234567890123, ', 60);
rstAxa.AddNew();
fld = flds.Item('str1' ); fld.Value(strValue);
fld = flds.Item('str2' ); fld.Value(strValue);
fld = flds.Item('str3' ); fld.Value(strValue);
fld = flds.Item('str4' ); fld.Value(strValue);
fld = flds.Item('str5' ); fld.Value(strValue);
fld = flds.Item('str6' ); fld.Value(strValue);
fld = flds.Item('str7' ); fld.Value(strValue);
fld = flds.Item('str8' ); fld.Value(strValue);
fld = flds.Item('str9' ); fld.Value(strValue);
fld = flds.Item('str10'); fld.Value(strValue);
fld = flds.Item('str11'); fld.Value(strFormula);
rstAxa.Update();
strValue = strRep('ABCDEFGHIJKLM, ', 60);
rstAxa.AddNew();
fld = flds.Item('str1' ); fld.Value(strValue);
fld = flds.Item('str2' ); fld.Value(strValue);
fld = flds.Item('str3' ); fld.Value(strValue);
fld = flds.Item('str4' ); fld.Value(strValue);
fld = flds.Item('str5' ); fld.Value(strValue);
fld = flds.Item('str6' ); fld.Value(strValue);
fld = flds.Item('str7' ); fld.Value(strValue);
fld = flds.Item('str8' ); fld.Value(strValue);
fld = flds.Item('str9' ); fld.Value(strValue);
fld = flds.Item('str10'); fld.Value(strValue);
fld = flds.Item('str11'); fld.Value(strFormula);
rstAxa.Update();
wbks = xlApp.Workbooks();
wbk = wbks.Add();
wkss = wbk.Worksheets();
wks = wkss.Item(1);
rng = wks.Range('A1');
rng.CopyFromRecordset(rstAxa);
// оживление формул и вычисление значений
rng = wks.Range('K1:K2');
rng.FormulaR1C1( rng.Value2() );
rng.Copy();
rng.PasteSpecial(#xlPasteValues);
xlApp.CutCopyMode(false);
rng = wks.Columns();
rng = COM::createFromVariant(rng.Item('A:J'));
rng.Delete();
rstAxa.Close();
xlApp.Visible(true);
}
P.S. Ну, и чтобы совсем скрыться от пользователя с этими манипуляциями, можно после "оживления формул" удалить 10 колонок - от A до J:
X++:
rng = wks.Columns();
rng = COM::createFromVariant(rng.Item('A:J'));
rng.Delete();
P.P.S. Добавил этот фрагмент в джоб. Так же как и фрагмент, определяющий разделитель списка Excel (cм. ниже). Теперь результаты окончательно находятся не в ячейках K1 и K2, а в ячейках A1 и A2 (из-за удаления колонок A:J).