AXForum  
Вернуться   AXForum > Microsoft Dynamics AX > DAX: Программирование
All
Забыли пароль?
Зарегистрироваться Правила Справка Пользователи Сообщения за день Поиск Все разделы прочитаны

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 12.03.2009, 13:26   #1  
Gustav is offline
Gustav
Moderator
Аватар для Gustav
SAP
Лучший по профессии 2009
 
1,858 / 1152 (42) ++++++++
Регистрация: 24.01.2006
Адрес: Санкт-Петербург
Записей в блоге: 19
911 символов
Как выясняется, CopyFromRecordset загибается при длине строки более 911 символов (просто какой-то телефонный "привет" от службы спасения! )

О проблеме знают в мире: http://www.google.ru/search?hl=ru&q=...1&lr=&aq=f&oq=
но пока ничего утешительного я не нашёл.
Старый 12.03.2009, 13:33   #2  
Antoncheg is offline
Antoncheg
Участник
 
41 / 11 (1) +
Регистрация: 29.02.2008
Цитата:
Сообщение от Gustav Посмотреть сообщение
Как выясняется, CopyFromRecordset загибается при длине строки более 911 символов (просто какой-то телефонный "привет" от службы спасения! )

О проблеме знают в мире: http://www.google.ru/search?hl=ru&q=...1&lr=&aq=f&oq=
но пока ничего утешительного я не нашёл.
Вот что пишут по этому поводу в первой гугловской ссылке
Using ADO (ActiveX 2.8 Object Lib) with Excel 2003, I extract data from a
worksheet and copy it to another worksheet in the same workbook.
In Office 2007 everything is fine, but in Office XP and Office 2003 the
CopyFromRecordset fails if a field has more than 911 bytes.

Т.е. в 2007 офисе эта проблема исправлена...
Старый 12.03.2009, 13:50   #3  
Gustav is offline
Gustav
Moderator
Аватар для Gustav
SAP
Лучший по профессии 2009
 
1,858 / 1152 (42) ++++++++
Регистрация: 24.01.2006
Адрес: Санкт-Петербург
Записей в блоге: 19
Цитата:
Сообщение от Antoncheg Посмотреть сообщение
Т.е. в 2007 офисе эта проблема исправлена...
Получается, что так. Интересно, что ее также нет в более ранней Excel 2000 - я проверил, запустив там такой VBA-код с http://support.microsoft.com/kb/818808/en-us :
Код:
Sub XLTest()
Dim aValues(4)
 
  aValues(0) = "Test1"
  aValues(1) = "Test2"
  aValues(2) = "Test3"
 
  MsgBox "First the Good range set."
  aValues(3) = String(911, 65)
  
  Range("A1:D1").Value = aValues
 
  MsgBox "Now the bad range set."
  aValues(3) = String(912, 66)
  Range("A2:D2").Value = aValues 'вызывает ошибку
 
End Sub
Отмечу, что проблема существует лишь для массивов (очевидно, CopyFromRecordset тоже ими оперирует). Если выполнить оператор с простым (не "массивным") присвоением, то всё ОК:
Код:
Range("A2").Value = String(912, 66) ' нормально поместит 912 букв B в ячейку
Старый 12.03.2009, 13:57   #4  
Gustav is offline
Gustav
Moderator
Аватар для Gustav
SAP
Лучший по профессии 2009
 
1,858 / 1152 (42) ++++++++
Регистрация: 24.01.2006
Адрес: Санкт-Петербург
Записей в блоге: 19
Цитата:
Сообщение от Antoncheg Посмотреть сообщение
в отгрузку может попасть партия из 300 единиц одной номенклатуры и 500, что подразумевает более объемного формата строки.
Что если попробовать нарезать ваши 500 серийников на 10 колонок по 60, а в 11-й собрать при помощи формулы?
Цитата:
Сообщение от Antoncheg Посмотреть сообщение
Может быть попробовать какой-нибудь другой метод экспорта? Есть мнения?
Любой, который пишет поячеечно. Например, при помощи класса ComExcelDocument_RU. Если у вас не десятки тысяч записей (иначе будет долго), то можно попробовать.
Старый 12.03.2009, 14:08   #5  
Antoncheg is offline
Antoncheg
Участник
 
41 / 11 (1) +
Регистрация: 29.02.2008
Цитата:
Сообщение от Gustav Посмотреть сообщение
Что если попробовать нарезать ваши 500 серийников на 10 колонок по 60, а в 11-й собрать при помощи формулы?
Любой, который пишет поячеечно. Например, при помощи класса ComExcelDocument_RU. Если у вас не десятки тысяч записей (иначе будет долго), то можно попробовать.
ок, спасибо, буду пробовать. Нет, такого количества строк не набирается, отчет снимается ежедневно, поэтому ComExcelDocument_RU можно рассмотреть как альтернативу.
Старый 12.03.2009, 15:13   #6  
Gustav is offline
Gustav
Moderator
Аватар для Gustav
SAP
Лучший по профессии 2009
 
1,858 / 1152 (42) ++++++++
Регистрация: 24.01.2006
Адрес: Санкт-Петербург
Записей в блоге: 19
Цитата:
Сообщение от 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).
Теги
ado, excel, экспорт

 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
Исследование скорости экспорта данных из Axapta в Excel (коллективный эксперимент) Gustav DAX: База знаний и проекты 79 13.02.2014 13:18
[Excel] - Несколько версий Excel на машине клиента Андре DAX: Программирование 11 07.08.2007 13:45
Вызов Item() для коллекций Excel Владимир Максимов DAX: Программирование 15 17.08.2006 19:47
"Такая строка уже сущ." при переносе из Excel! Zelenhof DAX: Программирование 2 13.01.2003 13:41
Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра
Комбинированный вид Комбинированный вид

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход

Рейтинг@Mail.ru
Часовой пояс GMT +3, время: 06:10.