-41 / 49 / 5
Регистрация: 10.01.2017
Сообщений: 1,915

Чтение/запись в Excel с COM OLE C++

24.01.2019, 21:21. Показов 57876. Ответов 71
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Здравствуйте,

Подскажите пожалуйста, есть ли у кого пример кода чтения и записи данных из/в откртый ексель файл с помощью COM/OLE на чистом С++.

Есть микрософтовский пример:
https://support.microsoft.com/... -or-import

Он создает ексель файл и записывает в него данные, но как записать данные в уже открытый ексель, как этот ексель файл отловить, такого примера нет, а доработать/изменить микрософтовский примера под свою задачу, для меня на данный момент, к сожалению совершенно не возможно, настолько там все сложно.

Может кто нибудь делал нечто подобное.
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
24.01.2019, 21:21
Ответы с готовыми решениями:

Cpp builder-Ole-Excel. WideString пишет в ячейку Excel минус перед нулем
Здравствуйте! Посмотрите пожалуйста: Когда аргумент val == 0, в ячейку Excel пишется "-0". Без WideString все нормально - в...

Общение с Excel через OLE
Недавно начал изучать с++. Использую ms vc++ 2010 express. Код такой // 2.cpp: определяет точку входа для консольного приложения. // ...

OLE. Как переименовать созданный файл в Excel.Application?
Доброго дня всем! Подскажите, как переименовать созданный файл в Excel? По умолчанию создается Книга1, а нужно другое имя документа. ...

71
6771 / 4565 / 1843
Регистрация: 07.05.2019
Сообщений: 13,726
30.01.2020, 20:54
Author24 — интернет-сервис помощи студентам
Цитата Сообщение от Optimus11 Посмотреть сообщение
Что Msdn имеет ввиду под zero-length string ? Стока нулевой длинны. Это как ?
Просто пустая строка - ""; strlen("') == 0
1
-41 / 49 / 5
Регистрация: 10.01.2017
Сообщений: 1,915
05.02.2020, 16:09  [ТС]
Подскажите пожалуйста, я правильно понимаю, что COM не дает возможность работать с файлом екселя, который не открыт ?
0
6771 / 4565 / 1843
Регистрация: 07.05.2019
Сообщений: 13,726
05.02.2020, 16:50
Цитата Сообщение от Optimus11 Посмотреть сообщение
Подскажите пожалуйста, я правильно понимаю, что COM не дает возможность работать с файлом екселя, который не открыт ?
Да, правильно. Напрямую с файлом там ты работать не можешь. Ты создаёшь приложение Excel, которое будет работать с файлом.
0
 Аватар для bedvit
1204 / 255 / 22
Регистрация: 20.05.2016
Сообщений: 1,125
Записей в блоге: 21
24.11.2020, 18:04
Возможно ли забирать и передавать массив Variant-ов по ссылке или указателю (а не по значению)? Ибо операции получения данных и выгрузка на лист Excel дольше чем сам расчет.
Сейчас делаю так:

Automation helper function...
Кликните здесь для просмотра всего текста
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
// AutoWrap() - Automation helper function...
HRESULT AutoWrap(int autoType, VARIANT *pvResult, IDispatch *pDisp, LPOLESTR ptName, int cArgs...) {
    va_list marker;// Begin variable-argument list...
    va_start(marker, cArgs);
    HRESULT hr = S_FALSE;
    if (!pDisp) {
        va_end(marker);
        return hr;
    }
    DISPPARAMS dp = { NULL, NULL, 0, 0 };// Variables used...
    DISPID dispidNamed = DISPID_PROPERTYPUT;
    DISPID dispID;
    char szName[255];
    WideCharToMultiByte(CP_ACP, 0, ptName, -1, szName, 256, NULL, NULL);// Convert down to ANSI
    hr = pDisp->GetIDsOfNames(IID_NULL, &ptName, 1, LOCALE_USER_DEFAULT, &dispID);// Get DISPID for name passed...
    if (FAILED(hr)) {
        va_end(marker);
        return hr;
    }
    VARIANT *pArgs = new VARIANT[cArgs + 1];// Allocate memory for arguments...
    for (int i = 0; i < cArgs; i++) {// Extract arguments...
        pArgs[i] = va_arg(marker, VARIANT);
    }
    dp.cArgs = cArgs;// Build DISPPARAMS
    dp.rgvarg = pArgs;
    if (autoType & DISPATCH_PROPERTYPUT) {// Handle special-case for property-puts!
        dp.cNamedArgs = 1;
        dp.rgdispidNamedArgs = &dispidNamed;
    }
    hr = pDisp->Invoke(dispID, IID_NULL, LOCALE_SYSTEM_DEFAULT, autoType, &dp, pvResult, NULL, NULL);// Make the call!
    if (FAILED(hr)) {
        va_end(marker);
        delete[] pArgs;
        return hr;
    }
    va_end(marker);
    delete[] pArgs;
    return hr;
}

C++
1
2
3
4
5
6
7
8
9
10
11
CComPtr <IDispatch> Selection; {
        CComVariant result;
        if (AutoWrap(DISPATCH_PROPERTYGET, &result, pExcelDisp, L"Selection", 0) != S_OK) { MessageBox(hwndExcel, L"Selection: ", L"XLL", MB_OK | MB_ICONERROR); return; }
        Selection = result.pdispVal;    }
 
    CComVariant array_in_out;
    if (AutoWrap(DISPATCH_PROPERTYGET, &array_in_out, Selection, L"Value", 0) != S_OK) { MessageBox(hwndExcel, L"ValueGET: ", L"XLL", MB_OK | MB_ICONERROR); return; }
 
//что-то делаю с array_in_out и далее выкладываю
 
if (AutoWrap(DISPATCH_PROPERTYPUT, NULL, Selection, L"Value", 1, array_in_out) != S_OK) { MessageBox(hwndExcel, L"ValuePUT: ", L"XLL", MB_OK | MB_ICONERROR); return; }
0
2 / 2 / 0
Регистрация: 27.04.2015
Сообщений: 60
21.01.2021, 14:22
Приветствую всех читающих

Пытаюсь работать с Экселем через OLE, а в частности использую функцию AutoWrap со страницы примера автоматизации от MS.

При попытках выбрать нужный лист, оно не работает, выдает ошибку гласящую, как я понял, о том что объект не подключен к COM (0x800401FD).
Ниже описал последовательность действий ("лишнее" убрал, потому это не полный код).
И вот при выборе диапазона ячеек (Range) вылетает ошибка.

Если же использовать "ActiveSheet" то работает нормально...

Я полагаю ошибка именно в последовательности, но в руководстве к этим командам не нашел никаких оговорок.
Пробовал применять к книге и листу "Activate" - без толку (зачем вообще это нужно?).


Кликните здесь для просмотра всего текста
C++
1
2
3
4
5
6
7
8
9
10
11
    AutoWrap(DISPATCH_PROPERTYGET, &result, pXlApp, _T("Workbooks"), 0);
    pXlBooks = result;
    AutoWrap(DISPATCH_METHOD, &result, pXlBooks, _T("Open"), 1, filePath);
    AutoWrap(DISPATCH_PROPERTYGET, &result, pXlBooks, _T("Item"), 1, index);
    pXlBook = result;
    AutoWrap(DISPATCH_PROPERTYGET, &result, pXlBook, _T("Sheets"), 0);
    pXlSheets = result;
    AutoWrap(DISPATCH_PROPERTYGET, &result, pXlSheets, _T("Item"), 1, index);
    pXlSheet = result;
    AutoWrap(DISPATCH_PROPERTYGET, &result, pXlSheet, _T("Range"), 1, parm);
    pXlRange = result;
0
-41 / 49 / 5
Регистрация: 10.01.2017
Сообщений: 1,915
21.01.2021, 15:13  [ТС]
Цитата Сообщение от Foton6 Посмотреть сообщение
Приветствую всех читающих

Пытаюсь работать с Экселем через OLE, а в частности использую функцию AutoWrap со страницы примера автоматизации от MS.

При попытках выбрать нужный лист, оно не работает, выдает ошибку гласящую, как я понял, о том что объект не подключен к COM (0x800401FD).
Ниже описал последовательность действий ("лишнее" убрал, потому это не полный код).
И вот при выборе диапазона ячеек (Range) вылетает ошибка.

Если же использовать "ActiveSheet" то работает нормально...

Я полагаю ошибка именно в последовательности, но в руководстве к этим командам не нашел никаких оговорок.
Пробовал применять к книге и листу "Activate" - без толку (зачем вообще это нужно?).
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
string Sheet_work_or_active = "ActiveSheet"; //  Или любое другое значение, если нужен лист по названию.
Sheet_name = "Name_List";                         //Название листа, если нужен лист по названию.
 
 
USES_CONVERSION; // Без этой штуки не работает A2OLE преобразование в LPOLESTR.
LPOLESTR Sheet_work_or_active_lpolestr = A2OLE(Sheet_work_or_active.c_str()); 
 
 
    int cArgs_parametr = 1;
        if (Sheet_work_or_active == "ActiveSheet")
        {
            cArgs_parametr = 0;
        }
        else
        {
            cArgs_parametr = 1;
        }
 
 
               //-------------------------------------------------------
        string textos_string_for_Sheet_Name;
        textos_string_for_Sheet_Name = Sheet_name;
        VARIANT Sheet_Name_bstr;
        Sheet_Name_bstr.vt = VT_BSTR;
        BSTR bstrTextos_for_Sheet_Name = _com_util::ConvertStringToBSTR(textos_string_for_Sheet_Name.c_str()); 
        Sheet_Name_bstr.bstrVal = ::SysAllocString(bstrTextos_for_Sheet_Name);
        VARIANT result;
        VariantInit(&result);
               //-------------------------------------------------------
 
 
 
        AutoWrap_write(DISPATCH_PROPERTYGET, &result, pXlApp, (LPOLESTR)Sheet_work_or_active_lpolestr, cArgs_parametr, Sheet_Name_bstr);
 
        pXlSheet = result.pdispVal;   //Этот AutoWrap возвращает имя Листа - активного или указанного по имени.
0
2 / 2 / 0
Регистрация: 27.04.2015
Сообщений: 60
21.01.2021, 15:36
Optimus11
Спасибо!
Но это как то не соответствует документации Оо
ActiveSheet - не должен принимать параметров: https://docs.microsoft.com/en-... ctivesheet

Да и выбирать лист по имени не очень удобно, по крайней мере мне хотелось бы по индексу.
Должен же быть более "правильный" способ работать с любым листом или я что-то не так понял?
А если несколько одноименных листов и в разных книга, то что выберется?
0
 Аватар для bedvit
1204 / 255 / 22
Регистрация: 20.05.2016
Сообщений: 1,125
Записей в блоге: 21
21.01.2021, 16:22
Foton6, вы что-то намудрили.
Вот, все работает нормально, массив забираю с листа нужного индекса
C++
1
2
3
4
5
6
7
    CComVariant array_in_out;
    {CComVariant result, p1(1), p2(L"A1:A2");
    if (AutoWrap(DISPATCH_PROPERTYGET, &result, pExcelDisp, L"Sheets", 0) != S_OK) { MessageBox(hwndExcel, L"Sheets: ", bedvitXLL, MB_OK | MB_ICONERROR); return -1; }
    if (AutoWrap(DISPATCH_PROPERTYGET, &result, result.pdispVal, L"Item", 1, p1) != S_OK) { MessageBox(hwndExcel, L"Item: ", bedvitXLL, MB_OK | MB_ICONERROR); return -1; }
    if (AutoWrap(DISPATCH_PROPERTYGET, &result, result.pdispVal, L"Range", 1, p2) != S_OK) { MessageBox(hwndExcel, L"Range: ", bedvitXLL, MB_OK | MB_ICONERROR); return -1; }
    if (AutoWrap(DISPATCH_PROPERTYGET, &array_in_out, result.pdispVal, L"Value", 0) != S_OK) { MessageBox(hwndExcel, L"ValueGET: ", bedvitXLL, MB_OK | MB_ICONERROR); return -1; }
    }
0
2 / 2 / 0
Регистрация: 27.04.2015
Сообщений: 60
21.01.2021, 16:54
bedvit
Мдаааа, опять видимо моя невнимательность сыграла, сейчас все работает хотя ничего не трогал можно сказать Оо
Ну и ладненько, а то я уж было подумал надо каждый объект активировать перед тем как с ним работать О.О
0
2 / 2 / 0
Регистрация: 27.04.2015
Сообщений: 60
22.01.2021, 00:39
Опять возник затык...
Пытаюсь очистить выбранный "Range" при помощи "Clear" или "ClearContents", но вылетает ошибка: 0x800a03ec

Методом тыка выяснил что это происходит при попытке чистить объединенные ячейки.
Попробовал вместо них использовать "Delete", но тогда прилетает диалог предупреждающий о потере данных и необходимости принять волевое решение и нажать да или нет.

Как с этим быть подскажите?
>_<

А пока гуглил приведенный номер ошибки выяснил что она может вылетать если новым экселем (2010+) открыть xls
и пытаться манипулировать ячейками в которых первым символом идет " = ". И единственный совет: убедитесь что у вас ни одна ячейка не начинается с "="...
0
2 / 2 / 0
Регистрация: 27.04.2015
Сообщений: 60
22.01.2021, 22:14
Хм, если записываемое значение это строка и она начинается с символа "=" то прилетает ошибка 0x80020009.

-6 часов, прелесть.
0
7 / 1 / 1
Регистрация: 06.10.2019
Сообщений: 57
10.04.2021, 21:36
Мне кажется, значение (value с англ.) нужно поменять в pXlRange и добавить в Console.WriteLine($@"_CRT_SECURE_NO_WARN INGS"). А вообще, когда ошибка появляется, можно так: "код_ошибки.metanit"
Миниатюры
Чтение/запись в Excel с COM OLE C++  
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
10.04.2021, 21:36
Помогаю со студенческими работами здесь

Задание диапазона ячеек при объединении (OLE-сервер Excel)
Добрый день. Столкнулась с такой проблемой: при работе с OLE-сервером Excel, при задании диапазона объединения ячеек, появилась...

Чтение из Excel в StringGrid
Здравствуйте! Как считать информацию из открытого файла Excel в StringGrid? Пробовала вот так: void __fastcall...

Работа с БД SQLite 3: чтение, запись
есть бд SQLite 3, раньше с SQLite не работал, подскажите как от туда считать данные и записать их туда

Чтение данных из Excel с Visual C++
Здраствуйте. Нужно запрограммировать считывание данных из Excel-файла на Visual C++ (MVS 2005). Какие библиотеки для этого требуется...

Запись и чтение Excel
Здраствуйте. Подскажите как реализировать возможность записывать информацию с полей в лист Excel. После записи, при выборе соответствующего...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
72
Ответ Создать тему
Опции темы

Новые блоги и статьи
Kubernetes с Apache Flink для обработки данных в реальном времени
Mr. Docker 17.05.2025
Kubernetes — это целая философия управления распределёнными приложениями. В отличие от "примитивных" решений вроде Docker Swarm, K8s (как его ласково называют в тусовке DevOps-инженеров) предлагает. . .
Использование декораторов в Python
py-thonny 17.05.2025
Если вы когда-нибудь задумывались о том, как красиво расширить функциональность кода без лишней возни и дублирования, декораторы в Python — та самая волшебная палочка, которую вы искали. По сути, это. . .
Как некоторые отстают в навыках поиска информации в сети. Дублирование страницы открытого адреса в сети.
Hrethgir 17.05.2025
. . . берём бразуер, для многих он является инструментом поиска информации в сети. Понятное дело, что чтобы переходить по сслыкам есть такая фишка - "открыть в новой вкладке", но, представим себе что вы. . .
Реализация многопоточных сетевых серверов на Python
py-thonny 16.05.2025
Когда сталкиваешься с необходимостью писать высоконагруженные сетевые сервисы, выбор технологии имеет критическое значение. Python, со своей элегантностью и высоким уровнем абстракции, может. . .
C# и IoT: разработка Edge приложений с .NET и Azure IoT
UnmanagedCoder 16.05.2025
Мир меняется прямо на наших глазах, и интернет вещей (IoT) — один из главных катализаторов этих перемен. Если всего десять лет назад концепция "умных" устройств вызывала скептические улыбки, то. . .
Гибридные квантово-классические вычисления: Примеры оптимизации
EggHead 16.05.2025
Гибридные квантово-классические вычисления — это настоящий прорыв в подходах к решению сложнейших вычислительных задач. Представьте себе союз двух разных миров: классические компьютеры, с их. . .
Использование вебсокетов в приложениях Java с Netty
Javaican 16.05.2025
HTTP, краеугольный камень интернета, изначально был спроектирован для передачи гипертекста с минимальной интерактивностью. Его главный недостаток в контексте современных приложений — это. . .
Реализация операторов Kubernetes
Mr. Docker 16.05.2025
Концепция операторов Kubernetes зародилась в недрах компании CoreOS (позже купленной Red Hat), когда команда инженеров искала способ автоматизировать управление распределёнными базами данных в. . .
Отражение в C# и динамическое управление типами
stackOverflow 16.05.2025
Reflection API в . NET — это набор классов и интерфейсов в пространстве имён System. Reflection, который позволяет исследовать и манипулировать типами, методами, свойствами и другими элементами. . .
Настройка гиперпараметров с помощью Grid Search и Random Search в Python
AI_Generated 15.05.2025
В машинном обучении существует фундаментальное разделение между параметрами и гиперпараметрами моделей. Если параметры – это те величины, которые алгоритм "изучает" непосредственно из данных (веса. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru