С Новым годом! Форум программистов, компьютерный форум, киберфорум
Delphi для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.75/4: Рейтинг темы: голосов - 4, средняя оценка - 4.75
1 / 1 / 0
Регистрация: 07.09.2021
Сообщений: 101
1

Работа с отфильтрованными строками в Excel

22.03.2024, 10:54. Показов 777. Ответов 15
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Добрый день уважаемые форумчане.
Уже второй день ломаю голову над этой проблемой.
Нужно открыть книгу эксель, отфильтровать значения по цвету ячеек и из отфильтрованных ячеек в массив скопировать текстовые данные.
Если с открытием и фильтрацией проблем нет, то как считать данные из отфильтрованных ячеек? Меня уже скоро наверное в гугле забанят.

Вот процедура нажатия кнпки, которая запускает открытие и работу с эксель:

Кликните здесь для просмотра всего текста
Delphi
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
procedure TForm1.Button1Click(Sender: TObject);
var
m: array[1..100] of string;
i,j,colcount,rowcount: integer;
s: string;
begin
Try
Ap:= CreateOleObject('Excel.Application');
Ap.Workbooks.Open(OpenDialog1.FileName);
Ap.Sheets[1].Cells.Range['B1:B500'].AutoFilter(2,RGB(255,255,0),8,EmptyParam,True);
//Ap.Sheets[1].Cells.SpecialCells(xlCellTypeLastCell).Activate;
rowcount:=Ap.Sheets[1].UsedRange.Rows.Count;
//XL.Sheets[1].Cells.Range[Range].AutoFilter(8,RGB(255,255,0),8,EmptyParam,True);
Ap.Visible:=true;
      colcount:=Ap.Sheets[1].AutoFilter.Range.Columns[2].SpecialCells(xlVisible).Count;
       for i:=3 to colcount do
        begin
         [COLOR="Red"] s:=Ap.Sheets[1].Cells.Range['B2:B100','B'].End[xlUp].SpecialCells(xlCellTypeVisible).value
          //s:=Ap.Sheets[1].Cells.Range['B2:'+'B'+inttostr(i)].End[xlUp].SpecialCells(xlCellTypeVisible).value
          //m[i-3]:=VarToStr(Ap.Sheets[1].Cells.Range['B2:'+'B'+inttostr(i)].End[xlUp].SpecialCells(xlCellTypeVisible).value)
        end; [/COLOR]
//    ShowMessage(Ap.Sheets[1].AutoFilter.Range.Columns[2].SpecialCells(xlVisible).Row[1].value);
  Except
    ShowMessage('Что-то пошло не так');
    Ap.Application.Quit;
    Ap.Unassigned;
  end;
end;


Проблема в куске кода, выделенном красным. А он что-то не выделился. Тогда напишу его отдельно:
Delphi
1
s:=Ap.Sheets[1].Cells.Range['B2:B100','B'].End[xlUp].SpecialCells(xlCellTypeVisible).value
Я все никак не могу переделать пример из VB скрипта:

Visual Basic
1
2
3
1
Dim c As Range
For Each c In Range("A2", Cells(Rows.Count, "A").End(xlUp)).SpecialCells(xlCellTypeVisible)
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
22.03.2024, 10:54
Ответы с готовыми решениями:

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

Работа со строками в Excel
Помогите сделать задание! первая часть уже сделана, исходя из нее, надо сделать дальше! ...

Работа со строками и ячейками в excel
Добрый день. Сломал голову уже((( Имеются множество ячеек в которые я подтягиваю данные из текста...

Работа со строками Excel макрос
Всем добрый вечер. Есть формула в ячейке Excel ссылающаяся на ячейку в другой книге и принимающая...

15
5868 / 4596 / 1448
Регистрация: 14.04.2014
Сообщений: 20,393
Записей в блоге: 20
22.03.2024, 11:34 2
если количество строк не запредельно большое, я бы забил на это, передал бы все в делфи и отфильтровал бы уже здесь вообще без проблем
0
Эксперт Pascal/Delphi
4918 / 2786 / 854
Регистрация: 04.10.2012
Сообщений: 10,140
22.03.2024, 11:39 3
Цитата Сообщение от esgard Посмотреть сообщение
Проблема в куске кода
В чем она выражается? Конкретная ошибка?

Добавлено через 4 минуты
Не вижу у Вас в коде объявление констант

Delphi
1
2
3
4
const
 
xlUp = -4162;
xlCellTypeVisible = 12;
0
1 / 1 / 0
Регистрация: 07.09.2021
Сообщений: 101
22.03.2024, 11:56  [ТС] 4
Цитата Сообщение от krapotkin Посмотреть сообщение
если количество строк не запредельно большое, я бы забил на это, передал бы все в делфи и отфильтровал бы уже здесь вообще без проблем
если не смогу разобраться, то именно так и сделаю. А может вообще подключу таблицу как бд через АДО. Но это уже дело принципа)
Цитата Сообщение от droider Посмотреть сообщение
В чем она выражается? Конкретная ошибка?
Да, там ошибка олевариант
Насколько я успел разобраться в вб объявляется массив и этому массиву сразу же присваивается отфильтрованный массив ячеек excel. В делфи это ведь так не работает. Но вероятно этот фильтрованный массив можно присвоить стрингриду или дбгриду. Примеры какие то видел. После обеда посмотрю.
0
3048 / 1668 / 656
Регистрация: 19.03.2019
Сообщений: 5,372
22.03.2024, 14:58 5
esgard, если у тебя будут проблемы с тем, чтобы прочитать отфильтрованные ячейки, то воспользуйся советом, данным выше - читай все ячейки из нужного диапазона и в Delphi отбирай нужные.
0
3760 / 2264 / 705
Регистрация: 29.05.2013
Сообщений: 9,616
23.03.2024, 11:45 6
Цитата Сообщение от esgard Посмотреть сообщение
если не смогу разобраться, то именно так и сделаю. А может вообще подключу таблицу как бд через АДО. Но это уже дело принципа)
Так и надо было сделать сразу. Зачем вам такая сложная многоходовка с запуском ненужного в данной задаче экселя?
0
1 / 1 / 0
Регистрация: 07.09.2021
Сообщений: 101
23.03.2024, 14:49  [ТС] 7
Промучавшись еще денек, реши последовать вашим советам и тут же получил по лбу другой граблей:
для подключения к формату *.xlsx нужен ведь соответствующий ODBC драйвер. У меня стоит офис 2013х64. А делфи х32. И он этот драйвер не видит. Точнее не он, а адо.
Пробовал и так прописывать:
Delphi
1
AdoConnection1.ConnectionString:='Provider=Microsoft.ACE.OLEDB.12.0;Data Source='+OpenDialog1.FileName+';Extended Properties="Excel 12.0 Xml;HDR=YES"';
ну тут сразу понятно, этого драйвера нет.
и так:
Delphi
1
AdoConnection1.ConnectionString:='ODBCDriver={Microsoft Excel Driver (*.xls, *.xlsx, *.xlsm, *.xlsb)};DBQ='+opendialog1.filename+';';
и так и эдак ошибка одна и та же - не найден поставщик.
В ODBCx32 такая картина:

видимо потому что там судя по всему все равно драйвер для х64 прописан.
И тут проблему никак не обойти. кроме как сноса офиса х64 и заменой его на х32?
Миниатюры
Работа с отфильтрованными строками в Excel  
0
3760 / 2264 / 705
Регистрация: 29.05.2013
Сообщений: 9,616
23.03.2024, 17:51 8
Нет, для доступа к микрософтовским форматам данных, ставить офис нет необходимости, достаточно скачать с офсайта и установить Microsoft Access Database Engine 2016 Redistributable Конечно проще с базами акцес работать в акцесе, а с книгами эксел в экселе, но для доступа к данным они не обязательны.
0
1180 / 421 / 107
Регистрация: 31.03.2012
Сообщений: 1,150
24.03.2024, 19:58 9
esgard, посмотри (D7), возможно чем-то поможет
Кликните здесь для просмотра всего текста
Delphi
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
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
program jmTstExcel;
 
uses
  Windows, ActiveX, OleServer, OleCtrls, ADOInt, Variants, Classes, SysUtils, Dialogs,
  Excel_TLB, Office_TLB;
 
var
  LCID :Cardinal;
  od :TOpenDialog;
  ExcelBookName :string;
 
  oExcel :TExcelApplication;
  oWBook :_Workbook;
  oWSheet :_Worksheet;
{$warn symbol_platform off}
  oRng :ExcelRange; {$warn symbol_platform on}
  varArray :OleVariant;
  n, m :Integer;
 
begin
  od := TOpenDialog.Create(nil);
  with od do
    try
      InitialDir := ExtractFilePath(ParamStr(0));
      FileName := '*';
      if not Execute then
        Exit;
      { end if }
 
      ExcelBookName := FileName;
    finally Free;
    end; { end try }
  { end with }
 
  LCID := GetSystemDefaultLCID;
  if not Succeeded(CoInitializeEx(nil, COINIT_MULTITHREADED)) then
    Writeln('CoInitializeEx - error!')
  else begin
    oExcel := TExcelApplication.Create(nil);
    try
      oExcel.ConnectKind := ckNewInstance;
      oExcel.Connect;
      oExcel.AutoQuit := False;
      oExcel.Visible[LCID] := True;
      oExcel.DisplayAlerts[LCID] := False;
 
      oExcel.Workbooks.Open(  //function Open(
        ExcelBookName,        //  const Filename: WideString;
        EmptyParam,           //  UpdateLinks: OleVariant;
        EmptyParam,           //  ReadOnly: OleVariant;
        EmptyParam,           //  Format: OleVariant;
        EmptyParam,           //  Password: OleVariant;
        EmptyParam,           //  WriteResPassword: OleVariant;
        EmptyParam,           //  IgnoreReadOnlyRecommended: OleVariant;
        EmptyParam,           //  Origin: OleVariant;
        EmptyParam,           //  Delimiter: OleVariant;
        EmptyParam,           //  Editable: OleVariant;
        EmptyParam,           //  Notify: OleVariant;
        EmptyParam,           //  Converter: OleVariant;
        EmptyParam,           //  AddToMru: OleVariant;
        EmptyParam,           //  Local: OleVariant;
        EmptyParam,           //  CorruptLoad: OleVariant;
        LCID                  //  lcid: Integer): ExcelWorkbook; safecall;
      );
 
      oWBook := oExcel.ActiveWorkbook as _Workbook;
      // работаем с первым листом книги
      oWSheet := oWBook.Worksheets.Item[1] as _Worksheet;
 
      // выделим диапазон с данными из второго столбца
      oRng := oWSheet.Range[
          oWSheet.Cells.Item[1, 2],     // строка: 1, колонка: 2, т.е. начальная ячейка диапазона в терминах Excel: [B2]
          oWSheet.Range[                // этот диапазон состоит из одной ячейки (B2)
              oWSheet.Cells.Item[1, 2],
              oWSheet.Cells.Item[1, 2]
          ].End_[xlDown]                // и затем вниз по этой колонке до конца данных
      ];
 
      // отберем в этом диапазоне все ячейки закрашенные красным цветом
      oRng.AutoFilter(      //function AutoFilter(
        1,                  //  Field: OleVariant;
        rgb(255, 0, 0),     //  Criteria1: OleVariant;
        xlFilterCellColor,  //  Operator: XlAutoFilterOperator;
        EmptyParam,         //  Criteria2: OleVariant;
        EmptyParam          //  VisibleDropDown: OleVariant): OleVariant; dispid 793;
      );
      // добавим один лист в книгу в конец списка листов
      oWBook.Sheets.Add(                          //function Add(
        EmptyParam,                               //  Before: OleVariant;
        oWBook.Sheets.Item[oWBook.Sheets.Count],  //  After: OleVariant;
        1,                                        //  Count: OleVariant;
        xlWorksheet,                              //  Type_: OleVariant;
        LCID                                      //  lcid: Integer): IDispatch; safecall;
      );
      // переименуем добавленный лист, просто для прикола
      (oWBook.Sheets.Item[oWBook.Sheets.Count] as _Worksheet).Name := 'Добавленный';
 
      // скопируем отфильтрованные ячейки из нашего диапазона на добавленный лист, начиная с верхней левой ячейки: ... Cells.Item[1, 1]
      oRng.Copy(
        (oWBook.Sheets.Item[oWBook.Sheets.Count] as _Worksheet).Cells.Item[1, 1]
      );
 
      // исключаем из копии ячейки заголовка (заголовок из одной строки)
      oRng := oExcel.Intersect(
          (oWBook.Sheets.Item[oWBook.Sheets.Count] as _Worksheet).UsedRange[LCID],          // 1 - одна строка заголовка
          (oWBook.Sheets.Item[oWBook.Sheets.Count] as _Worksheet).UsedRange[LCID].Cells.Offset[1, 0]
      );
      varArray := oRng.Value[xlRangeValueDefault];
 
      // можно сразу получить вариантный массив не прибегая к промежуточному range, но громоздко
      //varArray := oExcel.Intersect(
      //    (oWBook.Sheets.Item[oWBook.Sheets.Count] as _Worksheet).UsedRange[LCID],
      //    (oWBook.Sheets.Item[oWBook.Sheets.Count] as _Worksheet).UsedRange[LCID].Cells.Offset[1, 0]
      //).Value[xlRangeValueDefault];
 
      // печать содержимого вариантного массива
      if VarIsArray(varArray) then begin
        for m := 1 to VarArrayHighBound(varArray, 1) do
          for n := 1 to VarArrayHighBound(varArray, 2) do
            case VarType(varArray[m, n]) of
              varOleStr:  Writeln('olestr  :', varArray[m, n]);
              varDouble:  Writeln('double  :', FloatToStr(varArray[m, n]));
              varDate:    Writeln('date    :', FormatDateTime('dd.mm.yyyy', varArray[m, n]));
              varInteger: Writeln('integer :', IntToStr(varArray[m, n]));
            else
              Writeln('<?>'); // хрен пойми что
            end; { end case }
          { end for }
        { end for }
      end; { end if }
 
    {$warn symbol_platform off}
      if DebugHook = 1 then begin
        Writeln('Do not close "Excel", press <Enter> here to continue....');
        Readln; // для организации паузы, чтобы можно было посмотреть на Excel-книгу
      end; { end if }
    {$warn symbol_platform on}
 
      // добавленный лист не удаляем, т.к. книгу не сохраняем
      oWBook.Saved[LCID] := True; { установим (True)!, якобы книга уже сохранена и закроем ее }
      oWBook.Close(               //procedure Close(
          False,                  //  SaveChanges: OleVariant;
          EmptyParam,             //  Filename: OleVariant;        { для якобы УЖЕ сохраненной книге имя не нужно }
          False,                  //  RouteWorkbook: OleVariant;
          LCID                    //  lcid: Integer); safecall;
      );
 
    finally
      // подчищаем за собой
      oWSheet._Release;  { Sheet }
      oWBook._Release;   { Books }
      oExcel.UserControl := True;
      oExcel.Quit;
      oExcel.Disconnect;
      CoUninitialize;
    end; { end try }
  end; { end if }
end.

Не по теме:

файлик Excel (2010) над которым издевался во вложении. второй столбец содержит условное форматирование, числа больше 50 выделены красным цветом. в третьем слолбце меньшие 50 - зеленым

Вложения
Тип файла: xlsx test.xlsx (10.9 Кб, 3 просмотров)
0
5868 / 4596 / 1448
Регистрация: 14.04.2014
Сообщений: 20,393
Записей в блоге: 20
24.03.2024, 20:15 10
Цитата Сообщение от esgard Посмотреть сообщение
А делфи х32
сама делфи x32
но программы-то можно и на x64 делать, и там это драйвер должен бы подхватиться
офиса у меня нет, поэтому проверить не могу
0
1 / 1 / 0
Регистрация: 07.09.2021
Сообщений: 101
25.03.2024, 08:43  [ТС] 11
Цитата Сообщение от Пытливый Посмотреть сообщение
установить Microsoft Access Database Engine 2016 Redistributable
это первое что я попытался сделать. х64 ставиться без проблем, но программой драйвер опять же не видится. А х32 отказывается ставится при установленном оффисе х64.

Цитата Сообщение от Joeymax Посмотреть сообщение
esgard, посмотри (D7), возможно чем-то поможет
Цитата Сообщение от Joeymax Посмотреть сообщение
Excel_TLB, Office_TLB;
эти два модуля ты сам писал?

Цитата Сообщение от krapotkin Посмотреть сообщение
но программы-то можно и на x64 делать, и там это драйвер должен бы подхватиться
А каким образом из под делфи х32 написать программу х64? Или я неверное понял мысль?.. Во всяком случае делфи 7 х64 вроде бы не существует. На что-то более новое тогда переходить.
0
Модератор
9628 / 6239 / 2422
Регистрация: 21.01.2014
Сообщений: 26,643
Записей в блоге: 3
25.03.2024, 09:08 12
Цитата Сообщение от esgard Посмотреть сообщение
делфи 7 х64 вроде бы не существует.
Да, нету такого.
Цитата Сообщение от esgard Посмотреть сообщение
На что-то более новое тогда переходить.
Ну, как бы, давно пора...
0
1180 / 421 / 107
Регистрация: 31.03.2012
Сообщений: 1,150
25.03.2024, 10:32 13
Цитата Сообщение от esgard Посмотреть сообщение
сам писал?
Menu -> Project -> Import Type Library -> выбираем [Microsoft Excel ... (Object library)]
устанавливаем галочку "Create Component Wrapper", указываем путь, где будут расположены сгенерированные модули (Unit dir name) и жмем кнопочку "Create unit"
0
5868 / 4596 / 1448
Регистрация: 14.04.2014
Сообщений: 20,393
Записей в блоге: 20
25.03.2024, 10:53 14
Цитата Сообщение от esgard Посмотреть сообщение
делфи 7 х64 вроде бы не существует.
в данном случае надо писать делфи 7 не существует
потому что если уж пользуетесь Д7, то и окружающая среда должна быть Windows XP и никаких проблем бы не было ??
0
1 / 1 / 0
Регистрация: 07.09.2021
Сообщений: 101
02.04.2024, 11:56  [ТС] 15
Цитата Сообщение от krapotkin Посмотреть сообщение
в данном случае надо писать делфи 7 не существует
потому что если уж пользуетесь Д7, то и окружающая среда должна быть Windows XP и никаких проблем бы не было ??
Цитата Сообщение от D1973 Посмотреть сообщение
Ну, как бы, давно пора...
Последовал вашему совету. Поставил Делфи 11 с возможностью компилировать программу под х64.
Но проблемы те же самые. опять ошибка при попытке коннекта к экселю.
Delphi
1
Driver={Microsoft Excel Driver (*.xls, *.xlsx, *.xlsm, *.xlsb)};DBQ=path to xls/xlsx/xlsm/xlsb file
Пробовал ставить пакет и 2013 и 2016 (в данный момент 2016) но все бестолку. И на странице майкрософт указана эта строка подключения и на других сайтах. Но, даже с установленным пакетом в списках драйверов нет “Microsoft.ACE.OLEDB.12.02". Ну мне то не принципиально, мне бы хоть как к xlsx подключиться.

Код подключения стандартный:
Кликните здесь для просмотра всего текста
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Try
//  ADOCOnnection1.ConnectionString:='Provider =Microsoft.ACE.OLEDB.12.0; Data Source =' + FN1 + '; Extended Properties ="Excel 8.0 Xml;HDR=YES";';
  ADOConnection1.ConnectionString:='Driver={Microsoft Excel Driver (*.xls, *.xlsx, *.xlsm, *.xlsb)};DBQ=' + FN1;
  ShowMessage(Adoconnection1.ConnectionString);
  ADOCOnnection1.Connected:=true;
  ADODataset1.EnableBCD:=true;
  DataSource1.Enabled:=true;
  ADOQuery1.SQL.Text:='SELECT * FROM "2"';
  ADOQuery1.Open;
  DBGrid1.Enabled:=true;
 
Except
   On Exception do;
 
End;


И опять эта ошибка:

"Debugger Exception Notification
---------------------------
Project Project1.exe raised exception class EDatabaseError with message 'Missing Connection or ConnectionString'."

Кликните здесь для просмотра всего текста
[ATTACH]
Работа с отфильтрованными строками в Excel
[/ATTACH]
0
1 / 1 / 0
Регистрация: 07.09.2021
Сообщений: 101
02.04.2024, 13:19  [ТС] 16
Аа, так там же есть FireDAC еще. Буду пробовать через него...
0
02.04.2024, 13:19
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
02.04.2024, 13:19
Помогаю со студенческими работами здесь

Работа с текстовыми строками. Создание макросов в Excel
Есть столбец.В каждой строке этого столбца описана полная характеристика товара. В этом столбце...

Формула крамера линейные уравнения. Работа со строками. Excel
Определить корни системы двух алгебраических уравнений с двумя неизвестными по формулам Крамера,...

Работа с текстовыми строками. Базовые операции со строками
1. Введите три отдельных символа. Проверьте, есть ли хотя бы в одном из них буква или цифра. 2....

Работа со строками, заполнить компоненты строками из файла
Привет! Нужна помощь в заполнении формы В общем, есть форма отправки письма. У нее есть 2 функции,...

Работа с текстовыми строками. Дополнительные работы со строками
кто поможет сделать задание Ввести два отдельный строки, которые содержат как минимум по 4 слова....

Работа со строками. Функции работы со строками
Дана строка символов. В заданном тексте определить позицию первой точки ‘ . ‘.

Работа со строками(операции над строками)
Пусть дана последовательность, содержащая от 2 до 50 слов, в каждом из которых от 1 до 8 строчных...


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

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