zlazic Ответов: 4

попытка добавить рабочий лист excel


У меня есть проект автоматизации производственного Оле C++, где я использую операторы import #взаимодействовать с приложением в формате Excel.
У меня возникли проблемы с добавлением нового рабочего листа после текущего (активного) рабочего листа.

следующий вызов добавит новую вкладку:
Добавить (vtMissing, vtMissing, (long)1, (long)xlWorksheet)

но я не знаю, каким должен быть 2-й аргумент для добавления нового листа.

Ссылка на объектную модель excel гласит, что она должна быть:

"Объект, указывающий лист, после которого добавляется новый лист."

Что это значит? У кого-нибудь есть идеи?

[no name]

Попробуйте заменить 2-й параметр индексом листа, который вы хотите вставить в новый лист. Если ваш активный лист имеет индекс 1, то попробуйте 1. Кроме того, вы можете использовать функцию перемещения, чтобы переместить лист туда, куда вы хотите.

4 Ответов

Рейтинг:
32

Volynsky Alex

Попробуйте что-нибудь использовать:

Excel:: _ApplicationPtr XL;
....

В формате Excel::_WorkbookPtr книги = ХL-&ГТ;книг-и gt;Добавить(в формате Excel::xlWorksheet);
В формате Excel::_WorksheetPtr лист = ХL->по параметру activesheet;
рабочий лист - > Name = " последняя страница";

лист = ХL-&ГТ;листы-и GT;добавить(); // добавление листов!!
рабочий лист - > Name = " другая страница";

лист = ХL-&ГТ;листы-и GT;добавить();
лист-и GT;имя = "некоторые страницы";

рабочий лист- & gt;SaveAs("c:\\test.xls");
рабочая тетрадь- & gt;закрыть();
XL - & gt;выйти();

Подробнее смотрите здесь:
http://stackoverflow.com/questions/5308464/create-multiple-excel-sheet-in-vc[^]


Или вы можете прочитать следующие статьи, я надеюсь, что это вам поможет:

Доступ к электронным таблицам Excel с помощью C++[^]

http://www.maths.manchester.ac.uk/~ахазель / EXCEL_C++. pdf[^]

http://blogs.technet.com/b/heyscriptingguy/archive/2005/12/15/how-can-i-add-additional-worksheets-to-an-excel-workbook.aspx[^]

http://msdn.microsoft.com/en-us/library/ff196568.aspx[^]


enhzflep

Разве этот код просто не добавляет новый лист после активного листа-то есть между первым и вторым листами?

Y.Desros

Точные ответы здесь
Спасибо Алексу за ваши вклады/примеры!

Рейтинг:
28

enhzflep

Вместо того чтобы индексировать коллекцию листов, необходимо предоставить функции допустимые объекты листа.

Запустив новый экземпляр excel и записав 2 макроса, мы получим следующий код:

1. Лист между &амп Лист2; Лист3 (Правой Кнопкой Мыши лист 3, Добавить новый лист)

Sheets("Sheet3").Select
Sheets.Add


2. Лист добавляется в конце, после всех листов
Sheets.Add After:=Sheets(Sheets.Count)


Фрагмент кода c++, который я только что собрал вместе, достигает #2:
(помня, что мы должны передавать args в обратном порядке для COM-вызовов)
// Get Workbooks collection
IDispatch *pXlBooks;
pXlBooks = getIDispatchVal(pXlApp, L"WorkBooks");

// Call Workbooks.Add() to get a new workbook...
 IDispatch *pXlBook;
 pXlBook = getIDispatchVal(pXlBooks, L"Add");

 IDispatch *pXlSheets;
 pXlSheets = getIDispatchVal(pXlBook, L"Worksheets");


 int curBookSheetCount = getCount(pXlSheets);
 IDispatch *aftrSheet = getItem(pXlSheets, curBookSheetCount);
 IDispatch *pNewSheet;
 {
     VARIANT result, var1,var2;
     VariantInit(&result);

     var1.pdispVal = NULL;
     var1.vt = VT_NULL;

     var2.pdispVal = aftrSheet;
     var2.vt = VT_DISPATCH;

     AutoWrap(DISPATCH_METHOD, &result, pXlSheets, L"Add", 2, var2, var1);
     pNewSheet = result.pdispVal;
 }


Пара моих вспомогательных функций:
int getCount(IDispatch *pCollection)
{
    VARIANT result;
    VariantInit(&result);
    result.pdispVal = NULL;
    AutoWrap(DISPATCH_PROPERTYGET, &result, pCollection, L"Count", 0);
    return result.lVal;
}

IDispatch *getItem(IDispatch *pCollection, int index)
{
    VARIANT result, param1;
    VariantInit(&result);
    result.pdispVal = NULL;
    param1.vt = VT_I4;
    param1.lVal = index;
    AutoWrap(DISPATCH_PROPERTYGET, &result, pCollection, L"Item", 1, param1);
    return(result.pdispVal);
}

// EDIT: I forgot this one.
IDispatch *getIDispatchVal(IDispatch *pObject, wchar_t *valName)
{
    VARIANT result;
    VariantInit(&result);
    AutoWrap(DISPATCH_PROPERTYGET, &result, pObject, valName, 0);
    return result.pdispVal;
}


Рейтинг:
2

armagedescu

У вас, вероятно, будет много таких вопросов. При работе с автоматизацией лучше сделать небольшие тестовые функции в VBA, просто чтобы посмотреть, как это работает. И после этого сделайте то же самое в C++. Поступая таким образом, вы гораздо быстрее поймете документацию, библиотеку типов и то, что именно нужно сделать.


Рейтинг:
1

JeongChan.Kim

_variant_t varBefore = vtMissing;
_variant_t varAfter = vtMissing;
_variant_t varCount = vtMissing;

int nCurSheetCount = pBook - & gt;Sheets-> GetCount();
int nTotalSheet = 5; / / подлежит изменению.

varCount = nTotalSheet - nCurSheetCount;
pSheet = pBook- & gt;Sheets - & gt;Item[nCurSheetCount];

varAfter.vt = VT_DISPATCH;
varAfter. pdispVal = pSheet;

pSheet = pBook- & gt;Sheets - & gt;Add(varBefore, varAfter, varCount);