NEW! Быстрый способ выгрузки в Excel без «геморроя» с помощью COMSafeArray.

Как очень быстро, легко и без всяких препятствий (драйвера ADODB, права пользователя Windows и т.п.) выгрузить данные в Excel с помощью COMSafeArray.

Заглянем в справку:

COMSafeArray  — объектная оболочка над многомерным массивом SAFEARRAY из COM. Позволяет создавать и использовать SAFEARRAY для обмена данными между COM-объектами.

Т.е., существует универсальный массив  для передачи данных между различными COM-объектами.  Всё что нужно, это 1С и Excel, ничего лишнего. Именно это привлекло моё внимание к этому объекту.

Скажу честно, мне пришлось потратить целый день, чтобы понять, как работать с этим объектом, в интернете ничего подобного мне не приходилось встречать. По этому пришлось стать первопроходцем.

Этот объект очень хитёр, т.к. при чтении файла из Excel возвращается массив в одном виде, а для передачи данных в Excel необходимо создать немного иной вариант. Но время было потрачено с пользой.

Кроме того, функция принимающая таблицу значений и сохраняющая данные в файл получилась универсальной. Теперь достаточно создать запрос с учётом некоторых нюансов и передать в эту функцию выгрузку запроса или таблицу значений.

Предложенная обработка спроектирована таким образом, что может быть вызвана как пользователем, так и регламентным заданием.

ОБРАТИТЕ ВНИМАНИЕ!

  1. Если в ТЗ будут строки из чисел, то как поступить, чтобы Excel не превратил их в числа, описано в публикации «Выгрузка данных в Excel без «геморроя». Один, но принципиально важный момент» (Ищите в моих публикациях).
  2. Учтите, Excel не понимает дат меньше 01.01.1900, по этому и пустую дату передавать нельзя, будет ошибка.
  3. ТЗ должна содержать только примитивные типы Дата, Число, Строка, Булево.

Эти нюансы, дополнительно, описаны в самой обработке.

Также, обратите внимание на статью «Как предотвратить возникновение ошибки при одновременном обращении пользователя и обработки к Excel»  (Ищите в моих публикациях).

10 Comments

  1. rasswet

    «по этому и пустую дату передавать нельзя»-натыкался на эти грабли. спасибо.

    Reply
  2. Evil Beaver

    Решение интересное, не знал что можно диапазон ячеек сразу задать в виде SAFEARRAY.

    Единственное замечание — уж очень много пафоса у вас в публикациях. Может попроще как-то?

    Краткая суть, для тех кому интересен принцип предлагаемого решения:

    // ИсходныйМассив — двумерный массив исходных данных (строки/колонки)
    // Размер — размерности массива (см. синтакс-помощник для ComSafeArray)
    Массив = Новый COMSafeArray(ИсходныйМассив, «VT_VARIANT», Размер);
    
    // Самое главное. диапазону ячеек можно просто присвоить SAFEARRAY со значениями.
    Лист.Range(Лист.Cells(2,1), Лист.Cells(Строк, Колонок)).Value = Массив;
    
    Reply
  3. Pr-Mex

    Ну, насчет того, что «в интернете ничего подобного мне не приходилось встречать. По этому пришлось стать первопроходцем.» у гугла есть другое мнение:

    https://www.google.ru/search?q=1%D1%81+SAFEARRAY&oq=1%D1%81+SAFEARRAY&aqs=chrome..69i57.3672j0j7&sourceid=chrome&espv=210&es_sm=93&ie=UTF-8#newwindow=1&q=site%3Amista.ru+excel+comSAFEARRAY

    Reply
  4. akor77

    (3) Pr-Mex, Действительно, в книге знаний описано, не натыкался. По Вашей ссылке нашлась только одна статья по выгрузке. Может я опять не так ищу. Но заметьте, там ни слова о граблях.

    Reply
  5. akor77

    (2) Evil Beaver, На счёт «пафоса» — учту. Писал «на радостях», это эмоции радости выплеснулись. Постараюсь быть сдержанней.

    Reply
  6. akor77

    В обработке есть ошибки:

    1. Поместить строку

    Лист.Range(Лист.Cells(2,1), Лист.Cells(Строк, Колонок)).Value = Массив;

    В попытку.

     Попытка
    Лист.Range(Лист.Cells(2,1), Лист.Cells(Строк, Колонок)).Value = Массив;
    Исключение
    Книга.Close();
    Книга = Неопределено;
    Excel.Interactive = Истина;
    Excel.DisplayAlerts = Истина;
    Excel.Application.Quit();
    Excel = Неопределено;
    Возврат «Ошибка при вставке массива. Подробно: » + ПодробноеПредставлениеОшибки(ИнформацияОбОшибке());
    КонецПопытки;
    

    Показать

    2. Переместить «возврат» ниже

     Попытка
    Книга.SaveAs(ПутьКФайлу, 56);
    Исключение
    Книга.Close();
    Книга = Неопределено;
    Возврат «Ошибка при записи файла. Подробно: » + ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()); // Отсюда
    Excel.Interactive = Истина;
    Excel.DisplayAlerts = Истина;
    Excel.Application.Quit();
    Excel = Неопределено;
    //Сюда
    КонецПопытки;
    

    Показать

    Reply
  7. DoctorRoza

    За идею +, за оформление -! 🙂

    Reply
  8. makc2k

    Данный подход чем то похож на метод excel CopyFromRST, когда результат адошного запроса сразу сбрасывается на лист. Только вот все равно тяжеловесный эксель нужно запускать. Тем не менее это кирпичик в копилку знаний.

    Reply
  9. nofx

    Хреново что нужно указывать границы диапазона области, если работаем с именованными областями.

    Reply
  10. user659124_s.kostina

    После выполнения обработки созданный файл Ексель будет висеть в процессах.

    Если рОткрыватьДляПросмотра Тогда
    #Если Клиент Тогда
    Ексель.Visible=Истина;
    #КонецЕсли
    КонецЕсли;
    //чтобы файл не висел в процессах после выполнения обработки
    Ексель.DisplayAlerts = 0;
    Ексель.Quit();
    Ексель.DisplayAlerts = 1;
    Ексель=Null;
    

    Показать

    Reply

Leave a Comment

Ваш адрес email не будет опубликован. Обязательные поля помечены *