Форум программистов, компьютерный форум, киберфорум
C++ Builder
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.59/22: Рейтинг темы: голосов - 22, средняя оценка - 4.59
dz_victor
1

Передача данный из StringGrid в "открытый" Excel

28.08.2010, 01:56. Показов 4314. Ответов 2
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Здравствуйте, форумчане, пиши (на C++ Builder 6) функцию передачи данный из StringGrid в Excel, с OLE объектами до этого не работал, так что начал рыть в интернете, в результате гугления настрадал вот такую функцию:

SaveGridToXLS(Form1->StringGrid1,"c:\\1.xls"); - если имя файла указано, то вывожу StringGrid в Excel и отрубаюсь, если имя файла пустое ("") - вывожу данные и делаю Excel видимым.

Код

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
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
//Функция: сохранить StringGrid в Excel--------------------------------------
void __fastcall TForm1::SaveGridToXLS(TStringGrid *Grid,AnsiString FileName)
{
  Variant
  Ex, //Переменная Excel.Application
  Wb, //Переменная WorkBook
  Sh; //Переменная WorkSheet
  OleInitialize(NULL);
  try //Попытка открыть приложение Excel
    {
      Ex=CreateOleObject("Excel.Application");
    }
    catch (...) //Попытка не удалась
      {
        Application->MessageBox("Не могу запустить сервер Microsoft Excel."
        " Возможно, Excel не установлен на компьютере.",
        "Ошибка",MB_OK+MB_ICONERROR);
        return;
      }
  Ex.OlePropertySet("Visible", false); //Отключение визуального режима Excel
  Ex.OlePropertySet("SheetsInNewWorkbook", 3); //Задание количества листов
  Ex.OlePropertyGet("WorkBooks").OleFunction("Add", 1); //Создание книги Excel
  Wb = Ex.OlePropertyGet("WorkBooks", 1);
  Sh=Ex.OlePropertyGet("WorkSheets",1);
  //Вывод StringGrid в Excel
  for (int Row = 0; Row < StringGrid1->RowCount; Row++)
    {
      for (int Col = 0; Col < StringGrid1->ColCount; Col++)
        {
          Sh.OlePropertyGet("Cells", Row + 1, Col + 1).OlePropertySet("Value",
          StringGrid1->Cells[Col][Row].c_str());
        }
    }
  if (FileName!="") //Если FileName не пустое
    {
      try //Попытка сохранить и закрыть приложение Excel
        {
          //НЕ отключить(true) вывод сообщений с вопросами типа "Заменить файл..."
          Ex.OlePropertySet("DisplayAlerts",false);
          //Сохранить книгу
          Ex.OlePropertyGet("Workbooks").OlePropertyGet("Item",1).
            OleProcedure("SaveAs",FileName.c_str());;
          //Закрыть открытое приложение Excel
          Ex.OleProcedure("Quit");
          Sh.Clear();
          Ex.Clear();
          OleUninitialize();
        }
        catch(...) //Попытка не удалась
          {
            MessageBox(0, "Ошибка при сохранении документа в формате .xls",
              "Ошибка", MB_OK);
            Ex.OleProcedure("Quit");
            Sh.Clear();
            Ex.Clear();
            OleUninitialize();
            return;
          }
    }
  else //Если FileName пустое
    {
      Ex.OlePropertySet("Visible", true); //Включить визуального режима Excel
      Sh.Clear();
      Ex.Clear();
      OleUninitialize();
    }
}
Однако все равно остались вопросы.... дальнейшие поиски результатов не дают - роюсь на одном месте, а толку ноль, если кто сталкивался, помогите пожалуйста.

ВОПРОСЫ:
1. ОСНОВНОЙ: Если я просто хочу вывести данные в Excel, то каждый раз создается новое окно, я так и не придумал как этого избежать.. т.е. - данные в StringGrid могую несколько раз изменяться и выводиться в Excel - но при повторном вызове функции создается новое окно, как сделать так, чтоб при повторном вызове изменения производились в том же окне (файле)....
2. при инициализации Ex=CreateOleObject("Excel.Application"); пробовал предворительно производить попытку подключения к уже существующему объекту Ex=GetActiveObject("Excel.Application"); - но в результате полезли ошибки, пришлось закоментировать этот кусок, не знаю, почему не работает?
3. сохранение в файл без визуализации работает нормально, единственная ошибка возникает, если файл для записи открыт, как избежать такой ошибки?
4. несколько раз встречал обращение к Excel через ExcelApplicatin1, в моем случае он вообще не используется, подходящего примера для ExcelApplicatin1 не нашел, так что сделал - так как смог - не лучше ли было использовать ExcelApplicatin1?
5. при передаче данных в Excel использовал простое копирование, в паре примеров находил копирование через буфер обмена или динамический массив Range, вроде как это лучше для быстродействия и концептуально правильнее, что посоветуете?

Зарание спасибо, если кто что посоветует - буду признателен.

Добавлено через 1 минуту

 Комментарий модератора 
Для выделения участков кода используйте соответствующие теги.
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
28.08.2010, 01:56
Ответы с готовыми решениями:

Как заставить запускать текущий (открытый в данный момент) проект?
Как заставить запускать текущий (открытый в данный момент) проект ?...кроме как через : правая...

Передача цвета строк и цвета текста из stringgrid в excel и обратно
Доброго дня. Интересует вопрос передачи цвета строк и цвета текста из stringgrid в excel и...

Передача данных в локальный HTML файл открытый в webbrouser
Доброе время суток. Есть html файл расположенный локально и есть некоторые данные на форме Как...

Запись данных в открытый файл Excel
Подскажите как дозаписывать данные в файл excel, если этот файл открыт. Суть программы:...

Как прочитать открытый файл Excel?
Добрый день, Нашел такой пример: excelapp = new Excel.Application(); excelapp.Visible =...

2
1360 / 988 / 119
Регистрация: 30.07.2010
Сообщений: 5,297
29.08.2010, 12:03 2
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
bool __fastcall TForm1::ExcelInit(void)
{
   bool Rezul t= false;
   try
   { // Попытка подключиться к открытому приложению Excel
      XL=Variant::GetActiveObject("Excel.Application");
      XLBooks=XL.OlePropertyGet("WorkBooks");
      Rezult=true;
   }
   catch(...)
   { //Попытка не удалась
      try
      { //Попытка открыть приложение Excel
         XL = Variant::CreateObject("Excel.Application");
         XLBooks = XL.OlePropertyGet("WorkBooks");
         Rezult = true;
      }
      catch (...)
      { //Попытка не удалась
         Application->MessageBox("Невозможно открыть Microsoft Excel!"
            "Возможно, Excel не установлен на компьютере.",
            "Ошибка",MB_OK+MB_ICONERROR);
      }
   }
   return Rezult;
}
вот так нужно инициализировать Excel. ошибки в (вопрос 2) будут возникать если Excel не запущен.
0
dz_victor
29.08.2010, 21:07 3
Спасибо, iama, я натыкался на этот пример на:

C Builder
Русское Сообщество Разработчиков
Немного о работе с Microsoft Excel
http://cppbuilder.ru/articles/0053.php

Там брал функцию ExcelInit(void), еще там были функции для открытия шаблона OpenSablon и копирования формы шаблона в отчет CopyRepFromSablon, но я так понял, что для простого вывода StringGrid в Excel они мне не нужны...?

Дело в том, что я пробовал вставлять эту функцию в свою прогу, но потом убрал, так как при запуске билдер ругался:

Project Project1.exe raised exception class EOleSysError with message "Operation Unavailable". Process Stopped. Use Step or Run to continue.

Сейчас пересмотрел внимательнее - в т.ч., попробовал запуск не из проекта, а из готового экзэшника - вроде все работает, т.е, как я понял - это была не ошибка, а здоровая реакция на "try", я прав?

Так что замечание было сделано не зря, но есть еще такой вопрос - с открытием/подключением к сервису Excel понятно, но все - если оставить так, как сейчас - билдер каждый раз создает новую книгу и пишет туда, а хочется добиться эффекта - "в одно окно" при клике на кнопочку "Открыть таблицу в Excel", т.е. в продолжение темы - Как ПИСАТЬ В ОДНУ КНИГУ...

Первое что приходит на ум - перезаписывать страницу в книге: получать активную книгу, получать страницу (активную/тупо первую) очищать ее и выводить по-новой, вроде, подобную функцию я в одном из примеров видел... но тогда вопрос - как узнать, что активна нужная страница?! как я понимаю при изложенном подходе будет либо создаваться новая кнгига, либо перезаписываться первая попавшаяся активная... Т.е., все, что приходит на ум - создавать/подключаться к Excel, сохранять в какой-нить "служебный файл" (вроде \\Temp.xls), который никто не будет открывать вручную, писать туда инфу, а потом загружать его в Excel и отображать.... так что ли... чего-то я тупить начинаю..
Поделитесть свежими мыслями по этой проблеме?
29.08.2010, 21:07
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
29.08.2010, 21:07
Помогаю со студенческими работами здесь

Как получить открытый доступ к Excel файлу
Всем привет! При компиляции своего кода столкнулся с такой проблемой: при нажатии кнопки номер три...

Как дозаписывать данные в открытый документ Excel
Подскажите как дозаписывать в открытый документ Excel. т.е. создается новый документ .xslx...

Ошибка при добавлениии шаблона в открытый файл Excel
При добавлении нового листа с шаблоном из файла выдается ошибка , код программы ...

Требуется из кода Vb вставить в открытый Excel-файл картинку
Всем привет! Требуется из кода Vb вставить в открытый Excel-файл картинку (логотип). Умею...

Не отображается на экране файл Excel, открытый макросом из PowerPoint
Sub Import_Data() n = InputBox(&quot;Введите путь к таблицам и название файла&quot;, , &quot;C:\FILE.xlsx&quot;) ...


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

Или воспользуйтесь поиском по форуму:
3
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru