Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > БД в Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 12.04.2015, 00:18   #1
as091isk
 
Регистрация: 30.06.2010
Сообщений: 7
По умолчанию Получить цвет ячейки EXCEL на Delphi.

Всем, доброго дня.

Уважаемые эксперты, помогите найти решение проблемы.

У меня есть лист EXCEL с данными, размером 50 строк х 250 столбцов.
Каждая ячейка помимо текста закрашена в один из 4 цветов - зеленый, красный, желтый, коричневый.

Подключаюсь к EXCEL через COM, естественно в потоке.
Данные с листа считываю через объект Range:
Код:
Result:=MyExcel.WorkSheets[WorksheetIndex].Range[R].Value;
Проблема в том, что Result содержит только текст. Мне нужен именно цвет каждой ячейки.

При прямом чтении цвета каждой ячейки получаю катастрофически низкую производительность приложения:
Код:
RangeColor:=MyExcel.WorkSheets[WorksheetIndex].Range[R];
for row:= 1 to 50 do begin
for col := 1 to 250 do begin
Color:=RangeColor.cells[row,col+5+c+1].Interior.Color;
......
.......
......
end;
end;
Что же делать, как же быть?

Последний раз редактировалось as091isk; 12.04.2015 в 00:31. Причина: правка блока кода
as091isk вне форума Ответить с цитированием
Старый 12.04.2015, 01:29   #2
kropotkina-alice
Форумчанин
 
Аватар для kropotkina-alice
 
Регистрация: 27.10.2014
Сообщений: 594
По умолчанию

Готовый ответ не дам, заставлю малость применить собственный мозг.
Вот вам пример для цвета шрифта:
Код:
Workbooks[1].WorkSheets[2].Range['B34'].Font.Color:=clRed
kropotkina-alice вне форума Ответить с цитированием
Старый 12.04.2015, 17:54   #3
as091isk
 
Регистрация: 30.06.2010
Сообщений: 7
По умолчанию

Попробовал ваш метод. Результаты неутешительные.

Код:
program Project1;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.SysUtils, System.Variants, System.StrUtils , System.Classes,System.UITypes,
  ComObj, ActiveX;


const EXCELAPP='Excel.Application';

var     MyExcel : OleVariant;

// функция проверяет, установлен ли EXCEL
function CheckExcelInstall:boolean;
var
 ClassID:TCLSID;
 Rez:HRESULT;
begin
 // ищем CLSID OLE - объекта
 Rez:=CLSIDFromProgID(PWideChar(WideString(EXCELAPP)), ClassID);
 if Rez = S_OK then Result:=true
               else Result:=false;
end;


function RunExcel(DisableAlerts:boolean=true; Visible: boolean=false): boolean;
begin
  try
{проверяем установлен ли Excel}
    if CheckExcelInstall then
      begin
        MyExcel:=CreateOleObject(ExcelApp);
//показывать/не показывать системные сообщения Excel (лучше не показывать)
        MyExcel.Application.EnableEvents:=DisableAlerts;
        MyExcel.Visible:=Visible;
        Result:=true;
      end
    else
      begin
        //MessageBox(0,'Приложение MS Excel не установлено на этом компьютере','Ошибка',MB_OK+MB_ICONERROR);
        Writeln('Приложение MS Excel не установлено на этом компьютере');
        Result:=false;
      end;
  except
    Result:=false;
  end;
end;

function OpenExcel(FileName:string):boolean;
begin
  try
    MyExcel.WorkBooks.Open(FileName);
    Result:=True;
  except
    Result:=false;
  end;
end;

function ExitExcel:boolean;
begin
  try
    if MyExcel.Visible then MyExcel.Visible:=false;
    MyExcel.Quit;
    MyExcel:=Unassigned;
    Result:=True;
  except
    Result:=false;
  end;
end;

// прочитать диапазон или ячейку  (строка)  i=0 --> кол-во листов
function WSRangeRead(WorksheetIndex:integer; R:string):Variant;//string;
begin
 try
   if WorksheetIndex=0 then WorksheetIndex:=MyExcel.WorkSheets.count;
   MyExcel.Worksheets[WorksheetIndex].Activate;
   //Result:=MyExcel.WorkSheets[WorksheetIndex].Range[R];//.ColorIndex;
   Result:=MyExcel.WorkSheets[WorksheetIndex].Range[R].Interior.Color;
  except
    Result:='Read error';
  end;
end;

//Из номера колонки и строки получаем ее буквенное значение
//Например Cells(2,2) будет равен Range(B2)
function GetAddressCells(num_col,num_row:integer):string;
var str_tmp:string;
begin
  str_tmp:='';
  str_tmp:=MyExcel.WorkSheets[1].Cells[num_col,num_row].address;
  Result:=StringReplace(str_tmp,'$','',[rfReplaceAll,rfIgnoreCase]);
end;

//-----------------------------------------------------------------------------\\
Procedure Dowork;

var f:textfile;

    ExcelFile  : string;
    RangeColor : Variant;

    row        : byte;
    col        : byte;

    Color      : TColor;
begin
  assignfile(f,'log.txt');
  append(f);
  Writeln(f,FormatDateTime('YYYY-MM-DD hh:mm:ss:zzz',noW));
  Closefile(f);

  CoInitializeEx(nil, COINIT_MULTITHREADED); //так правильнее, должно быстрее работать
  RunExcel;
  OpenExcel('C:\Users\Малой\Desktop\Новая папка2\Win32\Debug\Данные с датчиков Февраль.xlsx');

  for row := 1 to 35  do begin
  for col := 1 to 250 do begin
  Color:=MyExcel.Workbooks[1].WorkSheets[1].Range[GetAddressCells(row,col)].Interior.Color;
                         end;
                         end;
  ExitExcel;
  CoUninitialize;

  assignfile(f,'log.txt');
  append(f);
  Writeln(f,FormatDateTime('YYYY-MM-DD hh:mm:ss:zzz',noW));
  Closefile(f);
end;


begin
  try
    { TODO -oUser -cConsole Main : Insert code here }
    Dowork;
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;

end.
Время выполнения составило полторы минуты. Очень очень много.
Содержимое log.txt:

2015-04-12 17:47:46:504
2015-04-12 17:49:03:879



Дабы не быть голословным в приложении мое решение. (форум не позволяет более 5000 символов в сообщении).
Время выполнения составило около 40 секунд, что тоже очень много.
Содержимое log.txt:

2015-04-12 17:18:40:916
2015-04-12 17:19:26:992


Как мне кажется проблема в последовательном доступе к каждой ячейки.
Вложения
Тип файла: txt Unit1.txt (3.5 Кб, 133 просмотров)

Последний раз редактировалось as091isk; 12.04.2015 в 18:05.
as091isk вне форума Ответить с цитированием
Старый 12.04.2015, 19:33   #4
xxbesoxx
Участник клуба
 
Регистрация: 10.08.2010
Сообщений: 1,389
По умолчанию

Я бы приступил так . при нажатие кнопки импортировал это файл к БД хотя бы Access и потом начал закрашивать эту в Grid-е ячейки по условие и все ... выложите ваши файл Excel-а и скажите условие по каком он там должен закрашенный

kropotkina-alice красива дівчина христос воскрес

Последний раз редактировалось Stilet; 12.04.2015 в 19:57.
xxbesoxx вне форума Ответить с цитированием
Старый 12.04.2015, 19:50   #5
Аватар
Старожил
 
Аватар для Аватар
 
Регистрация: 17.11.2010
Сообщений: 18,922
По умолчанию

Цитата:
импортировал это файл к БД хотя бы Access и потом начал закрашивать эту в Grid-е ячейки по условие и все ...
И что, как узнать цвет ячеек?

Можно выгрузить как xml-книгу. И пропарсить его. Там в стилях есть цвета заливки и фона, а для каждой ячейки ссылка на стиль. Немного нудно, но зато быстро
Если бы архитекторы строили здания так, как программисты пишут программы, то первый залетевший дятел разрушил бы цивилизацию
Аватар вне форума Ответить с цитированием
Старый 12.04.2015, 19:54   #6
xxbesoxx
Участник клуба
 
Регистрация: 10.08.2010
Сообщений: 1,389
По умолчанию

Цитата:
И что, как узнать цвет ячеек?
Друг, Я так думаю что он там закрашены по какой то условие и не для красоты... и можно писать то условия
xxbesoxx вне форума Ответить с цитированием
Старый 12.04.2015, 20:06   #7
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Цитата:
for row := 1 to 35 do begin
for col := 1 to 250 do begin
Color:=MyExcel.Workbooks[1].WorkSheets[1].Range[GetAddressCells(row,col)].Interior.Color;
end;
end;
Во-первых:
Код:
var sht:OleVariant;
...
 with MyExcel.Workbooks[1].WorkSheets[1].Range[GetAddressCells(1,1),GetAddressCells(35,250)] do
  for row := 1 to 35  do begin
   for col := 1 to 250 do begin
    Color:=Cells[row,col].Interior.Color;
   end;
  end;
Это чуть ускорит работу, однако сразу возникает вопрос, а точнее два:
1) Куда смотрит оптимизатор?
2) Зачем нужно получать цвет, и где потом это используется?
Цитата:
CoInitializeEx(nil, COINIT_MULTITHREADED); //так правильнее, должно быстрее работать
Это из разряда мифов.
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 12.04.2015, 20:09   #8
Аватар
Старожил
 
Аватар для Аватар
 
Регистрация: 17.11.2010
Сообщений: 18,922
По умолчанию

Цитата:
и можно писать то условия
Про условия у ТС нужно спросить. А вдруг какой-то тайный смысл у цвета А с xml очень быстро, цвета ячеек не узнавал, но документы в виде xml-таблицы на несколько сотен строк и порядочное количество колонок мигом формируются, и экселя установленного не надо. То же, но через OLE очень долго
Если бы архитекторы строили здания так, как программисты пишут программы, то первый залетевший дятел разрушил бы цивилизацию
Аватар вне форума Ответить с цитированием
Старый 12.04.2015, 20:14   #9
xxbesoxx
Участник клуба
 
Регистрация: 10.08.2010
Сообщений: 1,389
По умолчанию

Цитата:
А вдруг какой-то тайный смысл у цвета
Да , да я так думаю
xxbesoxx вне форума Ответить с цитированием
Старый 12.04.2015, 22:26   #10
as091isk
 
Регистрация: 30.06.2010
Сообщений: 7
По умолчанию

Цитата:
Сообщение от Stilet Посмотреть сообщение
Во-первых:
Код:
var sht:OleVariant;
...
 with MyExcel.Workbooks[1].WorkSheets[1].Range[GetAddressCells(1,1),GetAddressCells(35,250)] do
  for row := 1 to 35  do begin
   for col := 1 to 250 do begin
    Color:=Cells[row,col].Interior.Color;
   end;
  end;
Это чуть ускорит работу, однако сразу возникает вопрос, а точнее два:
1) Куда смотрит оптимизатор?
2) Зачем нужно получать цвет, и где потом это используется?

Это из разряда мифов.
Да, действительно через
Код:
 Color:=Cells[row,col].Interior.Color;
работает чуточку быстрее. (делаю так в приложенном проекте).

Цитата:
Это чуть ускорит работу, однако сразу возникает вопрос, а точнее два:
1) Куда смотрит оптимизатор?
2) Зачем нужно получать цвет, и где потом это используется?
1) на увеличение скорости работы приложения. Если смотрю не туда, так ткни пальцем куда смотреть.
2) Нужно подсчитать количество переходов из зеленого цвета в желтый
as091isk вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Delphi и ячейки excel Ks2010 Общие вопросы Delphi 0 24.04.2012 11:37
ячейки в массив Excel и Delphi Fistashka Помощь студентам 0 18.12.2011 13:07
цвет ячейки stringgrid в delphi The Catalyst Помощь студентам 0 01.12.2011 14:47
Delphi + Excel проверка ячейки на ошибку Tirendus Общие вопросы Delphi 0 26.02.2010 15:49