IPB
ЛогинПароль:

> Внимание!

1. Пользуйтесь тегами кода. - [code] ... [/code]
2. Точно указывайте язык, название и версию компилятора (интерпретатора).
3. Название темы должно быть информативным. В описании темы указываем язык!!!

 
 Ответить  Открыть новую тему 
> С++ Builder6 & Excel
18192123
сообщение 4.10.2009 21:10
Сообщение #1


Профи
****

Группа: Пользователи
Сообщений: 920
Пол: Женский
Реальное имя: Марина

Репутация: -  2  +


Здравствуйте!

Подскажите пожалуйста, можно ли содержимое компонента-таблицы StringGrid экспортировать в документ Excel?
Если да, то как это делается?
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
volvo
сообщение 4.10.2009 21:16
Сообщение #2


Гость






Можно... В Drkb есть пример на Дельфи: "VCL -> TStringGrid -> Сохранение и загрузка, импорт и экспорт -> Экспорт TStringGrid в Excel", я думаю, что перенести на Builder не составит труда?
 К началу страницы 
+ Ответить 
18192123
сообщение 4.10.2009 21:21
Сообщение #3


Профи
****

Группа: Пользователи
Сообщений: 920
Пол: Женский
Реальное имя: Марина

Репутация: -  2  +


Цитата(volvo @ 4.10.2009 22:16) *

Можно... В Drkb есть пример на Дельфи: "VCL -> TStringGrid -> Сохранение и загрузка, импорт и экспорт -> Экспорт TStringGrid в Excel", я думаю, что перенести на Builder не составит труда?

Спасибо, справлюсь:)
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
18192123
сообщение 16.10.2009 18:53
Сообщение #4


Профи
****

Группа: Пользователи
Сообщений: 920
Пол: Женский
Реальное имя: Марина

Репутация: -  2  +


 
#include <vcl.h>
#include <math.h>
#pragma hdrstop

#include <utilcls.h>
#include <sysvari.h>
#include <ComObj.hpp>

#include "Unit_Stochastic_variables.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm2MS *Form2MS;

.......

AnsiString RefToCell(int ARow, int ACol)
{
  return ("A" + ACol - 1) + IntToStr(ARow);
}
//---------------------------------------------------------------------------
bool SaveAsExcelFile(TStringGrid AGrid, AnsiString ASheetName, AnsiString AFileName)
{
  int xlWBATWorksheet = -4167;
  int Row, Col;
  AnsiString GridPrevFile;
  OleVariant XLApp, Sheet, Data;
  int i, j;
  // Prepare Data
  Data = VarArrayCreate([1, AGrid.RowCount, 1, AGrid.ColCount], varVariant);
  for (i=0;i<=AGrid.ColCount-1;i++)
    for (j=0;j<=AGrid.RowCount-1;j++)
      Data[j+1][i+1] = AGrid.Cells[i][j];
  // Create Excel-OLE Object
  Result = false;
  XLApp = CreateOleObject("Excel.Application");
  try
  {
    // Hide Excel
    XLApp.Visible = false;
    // Add new Workbook
    XLApp.Workbooks.Add(xlWBatWorkSheet);
    Sheet = XLApp.Workbooks[1].WorkSheets[1];
    Sheet.Name = ASheetName;
    // Fill up the sheet
    Sheet.Range[RefToCell(1, 1), RefToCell(AGrid.RowCount,
      AGrid.ColCount)].Value = Data;
    // Save Excel Worksheet
    try
    {
      XLApp.Workbooks[1].SaveAs(AFileName);
      Result = true;
    }
    catch (...)
    {
      // Error ?
    }
  catch (...)
  {
    // Quit Excel
    if (!VarIsEmpty(XLApp))
    {
      XLApp.DisplayAlerts = false;
      XLApp.Quit;
      XLAPP = Unassigned;
      Sheet = Unassigned;
    }
   }
  }
}




и вооот такой список ошибок..
[C++ Error] Unit_Stochastic_variables.cpp(66): E2188 Expression syntax
[C++ Error] Unit_Stochastic_variables.cpp(69): E2247 '_fastcall Variant::operator [](const int)' is not accessible
[C++ Error] Unit_Stochastic_variables.cpp(71): E2451 Undefined symbol 'Result'
[C++ Error] Unit_Stochastic_variables.cpp(76): E2288 Pointer to structure required on left side of -> or ->*
[C++ Error] Unit_Stochastic_variables.cpp(78): E2316 'Workbooks' is not a member of 'OleVariant'
[C++ Error] Unit_Stochastic_variables.cpp(78): E2451 Undefined symbol 'xlWBatWorkSheet'
[C++ Error] Unit_Stochastic_variables.cpp(79): E2316 'Workbooks' is not a member of 'OleVariant'
[C++ Error] Unit_Stochastic_variables.cpp(80): E2316 'Name' is not a member of 'OleVariant'
[C++ Error] Unit_Stochastic_variables.cpp(82): E2316 'Range' is not a member of 'OleVariant'
[C++ Error] Unit_Stochastic_variables.cpp(87): E2316 'Workbooks' is not a member of 'OleVariant'
[C++ Error] Unit_Stochastic_variables.cpp(93): E2174 The '...' handler must be last
[C++ Error] Unit_Stochastic_variables.cpp(97): E2064 Cannot initialize 'const Variant &' with 'OleVariant'
[C++ Error] Unit_Stochastic_variables.cpp(97): E2342 Type mismatch in parameter 'V' (wanted 'const Variant &', got 'OleVariant')
[C++ Error] Unit_Stochastic_variables.cpp(99): E2316 'DisplayAlerts' is not a member of 'OleVariant'
[C++ Error] Unit_Stochastic_variables.cpp(100): E2316 'Quit' is not a member of 'OleVariant'
[C++ Error] Unit_Stochastic_variables.cpp(101): E2451 Undefined symbol 'XLAPP'
[C++ Error] Unit_Stochastic_variables.cpp(106): E2252 'catch' expected
[C++ Warning] Unit_Stochastic_variables.cpp(106): W8070 Function should return a value
[C++ Warning] Unit_Stochastic_variables.cpp(106): W8004 'xlWBATWorksheet' is assigned a value that is never used

Большое количество ошибок типа "is not member of OleVariant", и поскольку имею дело с Билдером, не знаю как переделать..
Помогите пожалуйста довести до ума начатое!
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
volvo
сообщение 16.10.2009 20:14
Сообщение #5


Гость






Не-не-не... smile.gif Билдер - это тебе не Дельфи, тут вся работа происходит через OlePropertyGet/OlePropertySet/OleFuntion/OleProcedure... Вот так работает экспорт в Excel:
bool SaveAsExcelFile(TStringGrid *AGrid, AnsiString ASheetName, AnsiString AFileName)
{
	const int xlWBATWorksheet = -4167;

	int bounds[4] = {0, AGrid->RowCount, 0 , AGrid->ColCount };
	Variant Array = VarArrayCreate(bounds, 3, varVariant);
	for(int i = 0; i < AGrid->RowCount; i++)
	{
		for(int j = 0; j< AGrid->ColCount; j++)
		{
			Array.PutElement(AGrid->Cells[j][i], i, j );
		}
	}

	Variant XLApp = CreateOleObject("Excel.Application");
	try
	{
		// Hide Excel
		XLApp.OlePropertySet("Visible", false);
		// Add new Workbook
		XLApp.OlePropertyGet("WorkBooks").OleFunction("Add", xlWBATWorksheet);

		Variant Sheet =
			XLApp.OlePropertyGet("Workbooks").OlePropertyGet("Item", 1).
				  OlePropertyGet("Worksheets").OlePropertyGet("Item", 1);

		Sheet.OlePropertySet("Name", ASheetName.c_str());

		Variant Cell1 = Sheet.OlePropertyGet("Cells", 1, 1);
		Variant Cell2 = Sheet.OlePropertyGet("Cells", AGrid->RowCount + 1, AGrid->ColCount + 1);

		Variant fRange = Sheet.OlePropertyGet("Range", Cell1, Cell2);
		fRange.OlePropertySet("Value", Array);

		XLApp.OlePropertySet("DisplayAlerts",false);
		XLApp.OlePropertyGet("Workbooks").OlePropertyGet("Item", 1).OleProcedure("SaveAs", AFileName.c_str());
		XLApp.OleProcedure("Quit");
	}
	catch(...)
	{
		//
		ShowMessage("Экспорт данных - Ошибка !!!");
	}
}

void __fastcall TForm1::Button1Click(TObject *Sender)
{
	// Вызывать - так:
	SaveAsExcelFile(sgTable, "test", "F:\\aga.xls");
}
 К началу страницы 
+ Ответить 
18192123
сообщение 16.10.2009 21:04
Сообщение #6


Профи
****

Группа: Пользователи
Сообщений: 920
Пол: Женский
Реальное имя: Марина

Репутация: -  2  +


Цитата(volvo @ 16.10.2009 21:14) *

Не-не-не... smile.gif Билдер - это тебе не Дельфи, тут вся работа происходит через OlePropertyGet/OlePropertySet/OleFuntion/OleProcedure... Вот так работает экспорт в Excel:

Ааа) Буду теперь знать! Спасибо!
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
18192123
сообщение 19.10.2009 19:49
Сообщение #7


Профи
****

Группа: Пользователи
Сообщений: 920
Пол: Женский
Реальное имя: Марина

Репутация: -  2  +


Натолкнулась ещё на одну проблему..
У меня в StringGrid во время выполнения программы помещается большое количество строк, и их количество больше, чем может вместить один лист в Excel. Можно как-то вставить ещё один лист в книгу, когда обнаружится недостаток строк для экспорта..? Помогите найти выход, пожалуйста!
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
volvo
сообщение 19.10.2009 21:33
Сообщение #8


Гость






Цитата
Можно как-то вставить ещё один лист в книгу, когда обнаружится недостаток строк для экспорта..?
Легко:
bool SaveAsExcelFile(TStringGrid *AGrid, AnsiString ASheetName, AnsiString AFileName)
{
	const int xlWBATWorksheet = -4167;
	const int maxRowsInXL = 550; // Изменишь на 65535 (XL 2002-2003) или 1048576 (XL 2007)

	Variant XLApp = CreateOleObject("Excel.Application");
	try
	{
		// Hide Excel
		XLApp.OlePropertySet("Visible", false);
		// Add new Workbook
		XLApp.OlePropertyGet("WorkBooks").OleFunction("Add", xlWBATWorksheet);

		Variant Sheet =
			XLApp.OlePropertyGet("Workbooks").OlePropertyGet("Item", 1).
				  OlePropertyGet("Worksheets").OlePropertyGet("Item", 1);

		int currStart = 0, counter = 1;
		// А теперь начинается самое интересное...
		while(currStart <= AGrid->RowCount)
		{
			Sheet.OlePropertySet("Name", (ASheetName + IntToStr(counter++)).c_str());

			int bounds[4] = {0, maxRowsInXL, 0 , AGrid->ColCount };
			Variant Array = VarArrayCreate(bounds, 3, varVariant);
			for(int i = 0; i < min(AGrid->RowCount, maxRowsInXL); i++)
			{
				for(int j = 0; j< AGrid->ColCount; j++)
				{
					Array.PutElement(AGrid->Cells[j][currStart + i], i, j );
				}
			}

			Variant Cell1 = Sheet.OlePropertyGet("Cells", 1, 1);
			Variant Cell2 = Sheet.OlePropertyGet("Cells", maxRowsInXL + 1, AGrid->ColCount + 1);

			Variant fRange = Sheet.OlePropertyGet("Range", Cell1, Cell2);
			fRange.OlePropertySet("Value", Array);

			currStart += maxRowsInXL;

			if(currStart <= AGrid->RowCount) {
				int count =
				XLApp.OlePropertyGet("Workbooks").OlePropertyGet("Item", 1).
					  OlePropertyGet("Worksheets").OlePropertyGet("Count");
				Variant AfterSheet =
				XLApp.OlePropertyGet("Workbooks").OlePropertyGet("Item", 1).
					  OlePropertyGet("Worksheets").OlePropertyGet("Item", count);
				Sheet =
				XLApp.OlePropertyGet("Workbooks").OlePropertyGet("Item", 1).
					  OlePropertyGet("Worksheets").OleFunction("Add", Variant().NoParam(), AfterSheet);
			}
		}

		XLApp.OlePropertySet("DisplayAlerts",false);
		XLApp.OlePropertyGet("Workbooks").OlePropertyGet("Item", 1).OleProcedure("SaveAs", AFileName.c_str());
		XLApp.OleProcedure("Quit");
	}
	catch(...)
	{
		ShowMessage("Экспорт данных - Ошибка !!!");
	}
}
(тестировал на Excel XP + BDS 2009 на СтрингГриде, содержащем 2000 строк. Так вот эти 200 строк были корректно разбиты на 4 листа)
 К началу страницы 
+ Ответить 
18192123
сообщение 6.11.2009 17:49
Сообщение #9


Профи
****

Группа: Пользователи
Сообщений: 920
Пол: Женский
Реальное имя: Марина

Репутация: -  2  +


Здравствуйте!

Теперь мне требуется импортировать данные из Excel в StringGrid.
Пример в DRKB данной операции я нашла, только возникли затруднения с тем, чтобы переделать примерчик на C++ - не знаю, какие методы нужно использовать взамен имеющихся..
Например, вот такое уже не воспринимается компилятором:

...
XLApp.Visible = False;  
// Open the Workbook  
XLApp.Workbooks.Open(AXLSFile);
...


Объясните пожалуйста, как это всё должно выглядеть?
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
volvo
сообщение 6.11.2009 18:08
Сообщение #10


Гость






Я ж написал выше:
Цитата
вся работа происходит через OlePropertyGet/OlePropertySet/OleFuntion/OleProcedure
Вот и работаем:
...
Variant XLApp = CreateOleObject("Excel.Application");
XLApp.OlePropertySet("Visible", false);
XLApp.OlePropertyGet("Workbooks").OlePropertyGet("Open", AXLSFile.c_str());
...
 К началу страницы 
+ Ответить 
18192123
сообщение 14.11.2009 10:41
Сообщение #11


Профи
****

Группа: Пользователи
Сообщений: 920
Пол: Женский
Реальное имя: Марина

Репутация: -  2  +


Попыталась переделать на C++ импорт из Excel
Но для некоторых моментов не знаю, что нужно использовать из методов OlePropertyGet/OlePropertySet/OleFuntion/OleProcedure...


bool Xls_To_StringGrid(TStringGrid AGrid,String AXLSFile)
{
  const xlCellTypeLastCell = 0x0000000B;
  OleVariant Sheet;
  Variant XLApp, RangeMatrix;
  int x, y, k, r;

  //Result := False;
  XLApp = CreateOleObject("Excel.Application");
  //try
  {
    XLApp.OlePropertySet("Visible", false);
    XLApp.OlePropertyGet("Workbooks").OlePropertyGet("Open", AXLSFile.c_str());
  //Sheet = XLApp.Workbooks[ExtractFileName(AXLSFile)].WorkSheets[1];
  //Sheet.Cells.SpecialCells(xlCellTypeLastCell, EmptyParam).Activate;
    x = XLApp.OlePropertyGet("ActiveCell").OlePropertyGet("Row");
    y = XLApp.OlePropertyGet("ActiveCell").OlePropertyGet("Column");

    AGrid.RowCount = x;
    AGrid.ColCount = y;

    //RangeMatrix = XLApp.Range['A1', XLApp.Cells.Item[X, Y]].Value;
    k = 1;
    while (k > x)
    {
      for (r=1;r<=y;r++)
        AGrid.Cells[(r - 1)][(k - 1)] = RangeMatrix[k][r];
      k++;
    }
    RangeMatrix = Unassigned;
  }
  catch(...)
  {
    ShowMessage("!!!");
  }
  if (!VarIsEmpty(XLApp)) then
  {
      XLApp.OlePropertySet("Quit");
      XLApp = Unassigned;
      Sheet = Unassigned;
      return true;
   }
   else
     return false;
}


void __fastcall TFormRegModel::ButClick(TObject *Sender)
{
  if (Xls_To_StringGrid(StringGrid1, 'D:\book1.xls'))
    ShowMessage('Table has been exported!');
}




Помогите разобраться, пожалуйста
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
volvo
сообщение 14.11.2009 14:45
Сообщение #12


Гость






Вот основа кода:
bool Xls_To_StringGrid(TStringGrid *AGrid, String AXLSFile)
{
	const xlCellTypeLastCell = 0x0000000B;
	Variant XLApp = CreateOleObject("Excel.Application");

		XLApp.OlePropertyGet("Application").OlePropertyGet("Workbooks").
			OleProcedure("Open", AXLSFile.c_str());
		XLApp.OlePropertySet("Visible", false);
		Variant Sheet = XLApp.OlePropertyGet("ActiveSheet");

		XLApp.OlePropertyGet("Cells").
			OlePropertyGet("SpecialCells", xlCellTypeLastCell).OleProcedure("Activate");
		int x = XLApp.OlePropertyGet("ActiveCell").OlePropertyGet("Row");
		int y = XLApp.OlePropertyGet("ActiveCell").OlePropertyGet("Column");
		AGrid->RowCount = x;
		AGrid->ColCount = y;

		for(int rows = 0; rows < x; rows++)
		{
			for(int cols = 0; cols < y; cols++)
			{
				AGrid->Cells[AGrid->FixedCols + cols][AGrid->FixedRows + rows] =
					Sheet.OlePropertyGet("Cells").
					OlePropertyGet("Item", rows + 1 , cols + 1);
			}
		}

	  Sheet = Unassigned;
	  XLApp.OlePropertyGet("Application").OleProcedure("Quit");
	  XLApp = Unassigned;
	  return true;
}

void __fastcall TFormRegModel::ButClick(TObject *Sender)
{
	if(Xls_To_StringGrid(StringGrid1, "D:\\book1.xls"))
	{
		ShowMessage("Table has been exported!");
	}
}
, всякие обработки исключений повесь сама...
 К началу страницы 
+ Ответить 

 Ответить  Открыть новую тему 
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 

- Текстовая версия 25.07.2025 9:03
Хостинг предоставлен компанией "Веб Сервис Центр" при поддержке компании "ДокЛаб"