Форум программистов, компьютерный форум, киберфорум
Delphi для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.91/11: Рейтинг темы: голосов - 11, средняя оценка - 4.91
0 / 0 / 0
Регистрация: 11.05.2013
Сообщений: 8

Delphi+Excel поиск максимума по модулю

11.05.2013, 20:21. Показов 2290. Ответов 11
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Доброго времени суток!
Есть программа на Delphi, которая использует числовые значения величин из результатов расчета программного комплекса. Нужно в сие торжество вписать кнопку, по которой будет отыскиваться максимальные по модулю значения в столбцах чисел. Пример таблицы:
А В С
1 -4 -10
-5 2 8
6 3 1 max: 6,4,10. Рад любой помощи)
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
11.05.2013, 20:21
Ответы с готовыми решениями:

Работа с StrinGrid в Delphi (поиск максимума по каждому столбцу двумерной матрицы)
Привет, ребят))) помогите, плиз, найти ошибку в коде, уже несколько дней голову ломаю :( Цель работы такова: необходимо создать...

Поиск в Excel по листам - Delphi
Здравствуйте, мне срочно нужна помощь! Мне нужно написать программу, которая искала бы при вводе в Edit имени в листах Excel совпадения и...

поиск по книге excel в delphi
Други, подскажите как реализовать поиск ячейки по всей книге excel в delphi? Сломал ноги. Не могу найти...

11
 Аватар для Arkaniy
107 / 107 / 21
Регистрация: 29.08.2012
Сообщений: 453
12.05.2013, 14:55
Delphi
1
2
3
4
5
6
7
for i := 1 to 3 do
 begin
  max := 0;
  for j := 1 to 3 do
   If max < abs(a[j,i]) then max := abs(a[j,i]);
  Label1.Caption := Label1.Caption +#32+ IntToStr(max);
 end;
В лэйбл через пробел выводит 3 максимальных модуля соответственно трём столбцам.
1
0 / 0 / 0
Регистрация: 11.05.2013
Сообщений: 8
13.05.2013, 08:44  [ТС]
Не совсем то, файл excel имеет постоянное количество столбцов, но строк с числами количество может быть разным. И нужно чтобы программка влезала в xls файл для поиска таковых максимумов.

Добавлено через 16 часов 49 минут
нашел похожую тему, более менее стало понятно общение между delphi и excel, но не могу понять, как организовать именно поиск максимумов, если получается что столбцы считываются как string...
это поиск значения в третьем столбце по двум предыдущим.
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
var
  Excel: Variant;
  WBk : OleVariant;
  i:integer;
  C,A,B:string;
begin
 Excel := CreateOleObject('Excel.Application');
 WBk := Excel.WorkBooks.Open(ExtractFilePath(paramstr(0))+'test.xlsx',0,True);
   for i:=1 to Excel.ActiveSheet.UsedRange.Rows.Count do
      begin
        A:=Excel.Range['A'+inttostr(i)];
        B:=Excel.Range['B'+inttostr(i)];
         if (A=Edit1.Text) and (B=Edit2.Text) then
          begin
            C:=Excel.Range['C'+inttostr(i)];
            ListBox3.Items.Add(C);
          end;
      end;
Excel.ActiveWorkbook.Close;
Excel.Application.Quit;
end;
0
 Аватар для Mawrat
13114 / 5895 / 1708
Регистрация: 19.09.2009
Сообщений: 8,809
13.05.2013, 10:20
Можно сделать так. Данные из таблицы на листе MS Excel прочитать в вариантный массив. Затем, в этом массиве найти наибольшее значение в каждом из столбцов. Примечание - если ячейка на листе Excel оказывается пустой, то её числовое значение принимается равным нулю.
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
implementation
 
{$R *.dfm}
 
uses
  ComObj;
 
{Чтение данных с листа рабочей книги MS Excel в вариантный массив.
aRow, aCol - координаты верхней левой ячейки в области данных таблицы
на листе MS Excel. Область данных таблицы - это область таблицы,
исключая шапку и заголовочные столбцы (если такие имеются).
aCntCols - количество столбцов в таблице данных.}
function ExcelToArr(aExSh : Variant; const aRow, aCol, aCntCols : Integer) : Variant;
var
  exRng, exCell1, exCell2 : Variant;
  Row : Integer;
begin
  VarClear(Result);
  if VarIsClear(aExSh) or (aRow < 1) or (aCol < 1) or (aCntCols < 1) then
    Exit;
  {Левая верхняя ячейка диапазона с данными на листе MS Excel.}
  exCell1 := aExSh.Cells[aRow, aCol];
  {Определяем номер нижней строки в используемом диапазоне.
  Используемый диапазон - это прямоугольная область на листе MS Excel,
  которая охватывает все используемые ячейки. К используемым ячейкам
  относятся не только те ячейки, которые содержат данные, но и те,
  в которых изменено оформление или в которых записаны формулы.}
  Row := aExSh.UsedRange.Row + aExSh.UsedRange.Rows.Count - 1;
  //Если диапазон, где должны быть данные, пустой, то выходим.
  if Row < exCell1.Row then Exit;
  {Определяем положение правой нижней ячейки диапазона, в соответствие
  с количеством строк данных на листе MS Excel и в соответствие с количеством
  столбцов в StringGrid, исключая фиксированные столбцы.}
  exCell2 := exCell1.Offset[Row - exCell1.Row, aCntCols - 1];
  {Определяем диапазон с данными на листе MS Excel.}
  exRng := aExSh.Range[exCell1, exCell2];
  {Получаем данные диапазона в виде вариантного массива.}
  Result := exRng.Value;
end;
 
//Пример чтения данных с листа MS Excel с помощью процедуры ExcelToSg().
procedure TForm1.Button1Click(Sender: TObject);
var
  exApp, exBook, exSh : Variant;
  VArr : Variant;
  i, j : Integer;
  NumMax : Extended;
  Od : TOpenDialog;
begin
  Od := OpenDialog1; //OpenDialog1 уже должен быть на форме.
  if Od.InitialDir = '' then
    Od.InitialDir := ExtractFilePath( ParamStr(0) );
  if not Od.Execute then Exit;
  if not FileExists(Od.FileName) then begin
    MessageBox(0, 'Файл с заданным именем не найден. Действие отменено.'
      ,'Файл не найден', MB_OK + MB_ICONEXCLAMATION + MB_APPLMODAL);
    Exit;
  end;
 
  //Попытка подключиться к корневому объекту MS Excel.
  try
    exApp := CreateOleObject('Excel.Application');
  except
    MessageBox(0, 'Не удалось запустить MS Excel. Действие отменено.',
      'Ошибка', MB_OK + MB_ICONERROR + MB_APPLMODAL);
    Exit;
  end;
  //Делаем видимым окно MS Excel. На время отладки или на постоянной основе.
  exApp.Visible := True;
  //Открываем файл рабочей книги.
  exBook := exApp.WorkBooks.Open(FileName:=Od.FileName);
  //Получаем ссылку на первый лист рабочей книги.
  exSh := exBook.Worksheets[1];
  {Получаем данные с листа рабочей книги MS Excel и записываем их
  в вариантный массив.
  Здесь предполагается, что верхняя левая ячейка в области данных
  на листе MS Excel имеет координаты: aRow = 4, aCol = 3,
  количество столбцов с данными: aCntCols = 3.}
  VArr := ExcelToArr(exSh, 4, 3, 3);
  if VarIsClear(VArr) then begin
    MessageBox(0, 'На листе MS Excel нет данных. Действие отменено.',
      'Отмена', MB_OK + MB_ICONEXCLAMATION + MB_APPLMODAL);
    Exit;
  end;
 
  {Определяем наибольшее значение в каждом столбце. Результаты записываем
  в Мемо.}
  Memo1.Clear;
  for j := 1 to VarArrayHighBound(vArr, 2) do begin
    NumMax := VArr[1, j];
    for i := 2 to VarArrayHighBound(vArr, 1) do
      if VArr[i, j] > NumMax then
        NumMax := VArr[i, j];
    Memo1.Lines.Add('Столбец: ' + IntToStr(j)
      + ', наибольшее: ' + FloatToStr(NumMax))
  end;
end;
 
end.
1
0 / 0 / 0
Регистрация: 11.05.2013
Сообщений: 8
13.05.2013, 10:27  [ТС]
Но если эти столбцы имеют конкретное положение, но не находятся рядом? То есть между ними и справа/слева есть аналогичные данные, но они не интересны.
0
 Аватар для Mawrat
13114 / 5895 / 1708
Регистрация: 19.09.2009
Сообщений: 8,809
13.05.2013, 11:20
Тогда можно с помощью функции ExcelToArr() читать отдельные столбцы. Отдельный столбец запишется в вариантный массив, состоящий из одного столбца. И в нём можно найти наибольший элемент. Так надо поступить для каждого интересующего столбца. Например, если нас инетересуют 3, 10 и 15 столбцы, то понадобится сделать такие вызовы:
Delphi
1
2
3
4
5
6
7
8
9
10
11
VArr := ExcelToArr(exSh, 4, 3, 1);
//Поиск наибольшего.
...
 
VArr := ExcelToArr(exSh, 4, 10, 1);
//Поиск наибольшего.
...
 
VArr := ExcelToArr(exSh, 4, 15, 1);
//Поиск наибольшего.
...
Добавлено через 38 минут
Сейчас значения пустых ячеек принимаются равными нулю. Поэтому, если окажется, что в столбце есть только ячейки с отрицательными числами и пустые ячейки, то ответ будет: 0 (ноль). - Это неверный результат. Чтобы исправить такую ситуацию, придётся анализировать содержимое каждой ячейки в столбце на листе Excel.
Delphi
1
2
3
4
5
6
...
if exCell.Text <> '' then begin
  Num := exCell.Value;
  if Num > NumMax then NumMax := Num;
end;
...
1
0 / 0 / 0
Регистрация: 11.05.2013
Сообщений: 8
14.05.2013, 18:19  [ТС]
Создаю button, memo, opendialog, но ничего не происходит при нажатии на button
0
 Аватар для Mawrat
13114 / 5895 / 1708
Регистрация: 19.09.2009
Сообщений: 8,809
14.05.2013, 22:07
Я разобрался с пустыми ячейками. Ранее я говорил:
Цитата Сообщение от Mawrat Посмотреть сообщение
Сейчас значения пустых ячеек принимаются равными нулю. Поэтому, если окажется, что в столбце есть только ячейки с отрицательными числами и пустые ячейки, то ответ будет: 0 (ноль). - Это неверный результат. Чтобы исправить такую ситуацию, придётся анализировать содержимое каждой ячейки в столбце на листе Excel.
Это не нужно делать - т. е., не надо проверять содержимое каждой ячейки. Элементы вариантного массива содержат сведения о типах данных, в том числе и о том - является ли ячейка пустой. Предположим, данные из диапазона ячеек Excel мы прочитали в вариантный массив VArr. Тогда:
- Если VarType(VArr[i, j]) = varEmpty - значит элемент соответствует пустой ячейке.
- Если VarType(VArr[i, j]) = varOleStr - значит элемент соответствует ячейке, в которой содержится текст.
- Если VarType(VArr[i, j]) = varDouble - значит элемент соответствует ячейке, в которой содержится число.
И т. д.
Цитата Сообщение от kolky Посмотреть сообщение
Создаю button, memo, opendialog, но ничего не происходит при нажатии на button
Я приложил к сообщению работающий проект и раб. книгу Excel с данными. В проекте учёл разбор типов данных. Теперь в подсчёте наибольшего числа учитываются только ячейки с числовыми данными. Ячейки с другими типами данных - пустые, с текстом и пр. - пропускаются (не учитываются).
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
implementation
 
{$R *.dfm}
 
uses
  ComObj;
 
{Чтение данных с листа рабочей книги MS Excel в вариантный массив.
aRow, aCol - координаты верхней левой ячейки в области данных таблицы
на листе MS Excel. Область данных таблицы - это область таблицы,
исключая шапку и заголовочные столбцы (если такие имеются).
aCntCols - количество столбцов в таблице данных.}
function ExcelToArr(aExSh : Variant; const aRow, aCol, aCntCols : Integer) : Variant;
var
  exRng, exCell1, exCell2 : Variant;
  Row : Integer;
begin
  VarClear(Result);
  if VarIsClear(aExSh) or (aRow < 1) or (aCol < 1) or (aCntCols < 1) then
    Exit;
  {Левая верхняя ячейка диапазона с данными на листе MS Excel.}
  exCell1 := aExSh.Cells[aRow, aCol];
  {Определяем номер нижней строки в используемом диапазоне.
  Используемый диапазон - это прямоугольная область на листе MS Excel,
  которая охватывает все используемые ячейки. К используемым ячейкам
  относятся не только те ячейки, которые содержат данные, но и те,
  в которых изменено оформление или в которых записаны формулы.}
  Row := aExSh.UsedRange.Row + aExSh.UsedRange.Rows.Count - 1;
  //Если диапазон, где должны быть данные, пустой, то выходим.
  if Row < exCell1.Row then Exit;
  {Определяем положение правой нижней ячейки диапазона, в соответствие
  с количеством строк данных на листе MS Excel и в соответствие с количеством
  столбцов в StringGrid, исключая фиксированные столбцы.}
  exCell2 := exCell1.Offset[Row - exCell1.Row, aCntCols - 1];
  {Определяем диапазон с данными на листе MS Excel.}
  exRng := aExSh.Range[exCell1, exCell2];
  {Получаем данные диапазона в виде вариантного массива.}
  Result := exRng.Value;
end;
 
//Чтение данных с листа MS Excel в вариантный массив и обработка данных.
procedure TForm1.Button1Click(Sender: TObject);
var
  exApp, exBook, exSh : Variant;
  VArr : Variant;
  i, j, Row : Integer;
  Num, NumMax : Extended;
  Od : TOpenDialog;
begin
  Od := OpenDialog1; //OpenDialog1 уже должен быть на форме.
  if Od.InitialDir = '' then
    Od.InitialDir := ExtractFilePath( ParamStr(0) );
  if not Od.Execute then Exit;
  if not FileExists(Od.FileName) then begin
    MessageBox(0, 'Файл с заданным именем не найден. Действие отменено.'
      ,'Файл не найден', MB_OK + MB_ICONEXCLAMATION + MB_APPLMODAL);
    Exit;
  end;
 
  //Попытка подключиться к корневому объекту MS Excel.
  try
    exApp := CreateOleObject('Excel.Application');
  except
    MessageBox(0, 'Не удалось запустить MS Excel. Действие отменено.',
      'Ошибка', MB_OK + MB_ICONERROR + MB_APPLMODAL);
    Exit;
  end;
  //Делаем видимым окно MS Excel. На время отладки или на постоянной основе.
  exApp.Visible := True;
  //Открываем файл рабочей книги.
  exBook := exApp.WorkBooks.Open(FileName:=Od.FileName);
  //Получаем ссылку на первый лист рабочей книги.
  exSh := exBook.Worksheets[1];
  {Получаем данные с листа рабочей книги MS Excel и записываем их
  в нефиксированные строки и столбцы таблицы Sg.
  Здесь предполагается, что верхняя левая ячейка в области данных
  на листе MS Excel имеет координаты: aRow = 4, aCol = 3,
  количество столбцов с данными: aCntCols = 3.}
  VArr := ExcelToArr(exSh, 4, 3, 3);
  if VarIsClear(VArr) then begin
    MessageBox(0, 'На листе MS Excel нет данных. Действие отменено.',
      'Отмена', MB_OK + MB_ICONEXCLAMATION + MB_APPLMODAL);
    Exit;
  end;
 
  {Определяем наибольшее значение в каждом столбце. Результаты записываем
  в Мемо.}
  Memo1.Clear;
  NumMax := 0;
  for j := 1 to VarArrayHighBound(vArr, 2) do begin
    Row := 0;
    for i := 1 to VarArrayHighBound(vArr, 1) do
      {Если данные являются числом, то обрабатываем их.
      Если элемент соответствует пустой ячейке, то VarType(VArr[i, j]) = varEmpty = 0.
      Если элемент соответствует ячейке с текстом, то VarType(VArr[i, j]) = varOleStr = 8}
      if VarType(VArr[i, j]) = varDouble then begin
        Inc(Row);
        Num := VArr[i, j];
        if Row = 1 then
          NumMax := Num
        else if Num > NumMax then
          NumMax := Num;
      end;
    if Row > 0 then
      Memo1.Lines.Add('Столбец: ' + IntToStr(j)
        + ', наибольшее: ' + FloatToStr(NumMax))
    else
      Memo1.Lines.Add('Столбец: ' + IntToStr(j)
        + ', в столбце нет числовых данных.');
  end;
end;
 
end.
Вложения
Тип файла: rar ExcelDataToVarArray-01.rar (180.9 Кб, 15 просмотров)
1
0 / 0 / 0
Регистрация: 11.05.2013
Сообщений: 8
19.05.2013, 18:21  [ТС]
Очень благодарен за работу! Еще вопрос такой, можно ли аналогично организовать для строк, а не для столбцов?
0
0 / 0 / 0
Регистрация: 11.05.2013
Сообщений: 8
20.05.2013, 19:50  [ТС]
"Бэн, это Данила. Ай нид хэлп"
0
0 / 0 / 0
Регистрация: 11.05.2013
Сообщений: 8
22.05.2013, 11:40  [ТС]
тема закрыта
0
 Аватар для Mawrat
13114 / 5895 / 1708
Регистрация: 19.09.2009
Сообщений: 8,809
23.05.2013, 12:55
Чтение строк из MS Excel и по-строчная обработка данных.
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
implementation
 
{$R *.dfm}
 
uses
  ComObj;
 
{Чтение группы строк с листа рабочей книги MS Excel в вариантный массив.
aRow, aCol - координаты верхней левой ячейки в области данных таблицы
на листе MS Excel. Область данных таблицы - это область таблицы,
исключая шапку и заголовочные столбцы (если такие имеются).
aCntRows - количество строк в таблице данных.}
function ExcelRowsToArr(aExSh : Variant; const aRow, aCol, aCntRows : Integer) : Variant;
var
  exRng, exCell1, exCell2 : Variant;
  Col : Integer;
begin
  VarClear(Result);
  if VarIsClear(aExSh) or (aRow < 1) or (aCol < 1) or (aCntRows < 1) then
    Exit;
  {Левая верхняя ячейка диапазона с данными на листе MS Excel.}
  exCell1 := aExSh.Cells[aRow, aCol];
  {Определяем номер правого крайнего столбца в используемом диапазоне.
  Используемый диапазон - это прямоугольная область на листе MS Excel,
  которая охватывает все используемые ячейки. К используемым ячейкам
  относятся не только те ячейки, которые содержат данные, но и те,
  в которых изменено оформление или в которых записаны формулы.}
  Col := aExSh.UsedRange.Column + aExSh.UsedRange.Columns.Count - 1;
  //Если диапазон, где должны быть данные, пустой, то выходим.
  if Col < exCell1.Column then Exit;
  {Определяем положение правой нижней ячейки диапазона, в соответствие
  с количеством столбцов данных на листе MS Excel.}
  exCell2 := exCell1.Offset[aCntRows - 1, Col - exCell1.Column];
  {Определяем диапазон с данными на листе MS Excel.}
  exRng := aExSh.Range[exCell1, exCell2];
  {Получаем данные диапазона в виде вариантного массива.}
  Result := exRng.Value;
end;
 
{Чтение данных с листа MS Excel в вариантный массив и
по-строчная обработка данных.}
procedure TForm1.Button2Click(Sender: TObject);
var
  exApp, exBook, exSh : Variant;
  VArr : Variant;
  i, j, Col : Integer;
  Num, NumMax : Extended;
  Od : TOpenDialog;
begin
  Od := OpenDialog1; //OpenDialog1 уже должен быть на форме.
  if Od.InitialDir = '' then
    Od.InitialDir := ExtractFilePath( ParamStr(0) );
  if not Od.Execute then Exit;
  if not FileExists(Od.FileName) then begin
    MessageBox(0, 'Файл с заданным именем не найден. Действие отменено.'
      ,'Файл не найден', MB_OK + MB_ICONEXCLAMATION + MB_APPLMODAL);
    Exit;
  end;
 
  //Попытка подключиться к корневому объекту MS Excel.
  try
    exApp := CreateOleObject('Excel.Application');
  except
    MessageBox(0, 'Не удалось запустить MS Excel. Действие отменено.',
      'Ошибка', MB_OK + MB_ICONERROR + MB_APPLMODAL);
    Exit;
  end;
  //Делаем видимым окно MS Excel. На время отладки или на постоянной основе.
  exApp.Visible := True;
  //Открываем файл рабочей книги.
  exBook := exApp.WorkBooks.Open(FileName:=Od.FileName);
  //Получаем ссылку на первый лист рабочей книги.
  exSh := exBook.Worksheets[1];
 
  {Получаем данные с листа рабочей книги MS Excel.
  Здесь предполагается, что верхняя левая ячейка в области данных
  на листе MS Excel имеет координаты: aRow = 5, aCol = 3,
  количество строк с данными: aCntRows = 3.}
  VArr := ExcelRowsToArr(exSh, 5, 3, 3);
  if VarIsClear(VArr) then begin
    MessageBox(0, 'На листе MS Excel нет данных. Действие отменено.',
      'Отмена', MB_OK + MB_ICONEXCLAMATION + MB_APPLMODAL);
    Exit;
  end;
 
  {Определяем наибольшее значение в каждой строке. Результаты записываем
  в Мемо.}
  Memo1.Clear;
  NumMax := 0;
  for i := 1 to VarArrayHighBound(vArr, 1) do begin
    Col := 0;
    for j := 1 to VarArrayHighBound(vArr, 2) do
      {Если данные являются числом, то обрабатываем их.
      Если элемент соответствует пустой ячейке, то VarType(VArr[i, j]) = varEmpty = 0.
      Если элемент соответствует ячейке с текстом, то VarType(VArr[i, j]) = varOleStr = 8}
      if VarType(VArr[i, j]) = varDouble then begin
        Inc(Col);
        Num := VArr[i, j];
        if Col = 1 then
          NumMax := Num
        else if Num > NumMax then
          NumMax := Num;
      end;
    if Col > 0 then
      Memo1.Lines.Add('Строка: ' + IntToStr(i)
        + ', наибольшее: ' + FloatToStr(NumMax))
    else
      Memo1.Lines.Add('Строка: ' + IntToStr(i)
        + ', в строке нет числовых данных.');
  end;
end;
 
end.
Функции для обработки столбцов и строк (как итог обсуждения):
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
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
implementation
 
{$R *.dfm}
 
uses
  ComObj;
 
{Чтение группы столбцов с листа рабочей книги MS Excel в вариантный массив.
aRow, aCol - координаты верхней левой ячейки в области данных таблицы
на листе MS Excel. Область данных таблицы - это область таблицы,
исключая шапку и заголовочные столбцы (если такие имеются).
aCntCols - количество столбцов в таблице данных.}
function ExcelColsToArr(aExSh : Variant; const aRow, aCol, aCntCols : Integer) : Variant;
var
  exRng, exCell1, exCell2 : Variant;
  Row : Integer;
begin
  VarClear(Result);
  if VarIsClear(aExSh) or (aRow < 1) or (aCol < 1) or (aCntCols < 1) then
    Exit;
  {Левая верхняя ячейка диапазона с данными на листе MS Excel.}
  exCell1 := aExSh.Cells[aRow, aCol];
  {Определяем номер нижней строки в используемом диапазоне.
  Используемый диапазон - это прямоугольная область на листе MS Excel,
  которая охватывает все используемые ячейки. К используемым ячейкам
  относятся не только те ячейки, которые содержат данные, но и те,
  в которых изменено оформление или в которых записаны формулы.}
  Row := aExSh.UsedRange.Row + aExSh.UsedRange.Rows.Count - 1;
  //Если диапазон, где должны быть данные, пустой, то выходим.
  if Row < exCell1.Row then Exit;
  {Определяем положение правой нижней ячейки диапазона, в соответствие
  с количеством строк данных на листе MS Excel.}
  exCell2 := exCell1.Offset[Row - exCell1.Row, aCntCols - 1];
  {Определяем диапазон с данными на листе MS Excel.}
  exRng := aExSh.Range[exCell1, exCell2];
  {Получаем данные диапазона в виде вариантного массива.}
  Result := exRng.Value;
end;
 
{Чтение группы строк с листа рабочей книги MS Excel в вариантный массив.
aRow, aCol - координаты верхней левой ячейки в области данных таблицы
на листе MS Excel. Область данных таблицы - это область таблицы,
исключая шапку и заголовочные столбцы (если такие имеются).
aCntRows - количество строк в таблице данных.}
function ExcelRowsToArr(aExSh : Variant; const aRow, aCol, aCntRows : Integer) : Variant;
var
  exRng, exCell1, exCell2 : Variant;
  Col : Integer;
begin
  VarClear(Result);
  if VarIsClear(aExSh) or (aRow < 1) or (aCol < 1) or (aCntRows < 1) then
    Exit;
  {Левая верхняя ячейка диапазона с данными на листе MS Excel.}
  exCell1 := aExSh.Cells[aRow, aCol];
  {Определяем номер правого крайнего столбца в используемом диапазоне.
  Используемый диапазон - это прямоугольная область на листе MS Excel,
  которая охватывает все используемые ячейки. К используемым ячейкам
  относятся не только те ячейки, которые содержат данные, но и те,
  в которых изменено оформление или в которых записаны формулы.}
  Col := aExSh.UsedRange.Column + aExSh.UsedRange.Columns.Count - 1;
  //Если диапазон, где должны быть данные, пустой, то выходим.
  if Col < exCell1.Column then Exit;
  {Определяем положение правой нижней ячейки диапазона, в соответствие
  с количеством столбцов данных на листе MS Excel.}
  exCell2 := exCell1.Offset[aCntRows - 1, Col - exCell1.Column];
  {Определяем диапазон с данными на листе MS Excel.}
  exRng := aExSh.Range[exCell1, exCell2];
  {Получаем данные диапазона в виде вариантного массива.}
  Result := exRng.Value;
end;
 
{Чтение данных с листа MS Excel в вариантный массив и
по-столбчатая обработка данных.}
procedure TForm1.Button1Click(Sender: TObject);
var
  exApp, exBook, exSh : Variant;
  VArr : Variant;
  i, j, Row : Integer;
  Num, NumMax : Extended;
  Od : TOpenDialog;
begin
  Od := OpenDialog1; //OpenDialog1 уже должен быть на форме.
  if Od.InitialDir = '' then
    Od.InitialDir := ExtractFilePath( ParamStr(0) );
  if not Od.Execute then Exit;
  if not FileExists(Od.FileName) then begin
    MessageBox(0, 'Файл с заданным именем не найден. Действие отменено.'
      ,'Файл не найден', MB_OK + MB_ICONEXCLAMATION + MB_APPLMODAL);
    Exit;
  end;
 
  //Попытка подключиться к корневому объекту MS Excel.
  try
    exApp := CreateOleObject('Excel.Application');
  except
    MessageBox(0, 'Не удалось запустить MS Excel. Действие отменено.',
      'Ошибка', MB_OK + MB_ICONERROR + MB_APPLMODAL);
    Exit;
  end;
  //Делаем видимым окно MS Excel. На время отладки или на постоянной основе.
  exApp.Visible := True;
  //Открываем файл рабочей книги.
  exBook := exApp.WorkBooks.Open(FileName:=Od.FileName);
  //Получаем ссылку на первый лист рабочей книги.
  exSh := exBook.Worksheets[1];
 
  {Получаем данные с листа рабочей книги MS Excel.
  Здесь предполагается, что верхняя левая ячейка в области данных
  на листе MS Excel имеет координаты: aRow = 4, aCol = 3,
  количество столбцов с данными: aCntCols = 3.}
  VArr := ExcelColsToArr(exSh, 4, 3, 3);
  if VarIsClear(VArr) then begin
    MessageBox(0, 'На листе MS Excel нет данных. Действие отменено.',
      'Отмена', MB_OK + MB_ICONEXCLAMATION + MB_APPLMODAL);
    Exit;
  end;
 
  {Определяем наибольшее значение в каждом столбце. Результаты записываем
  в Мемо.}
  Memo1.Clear;
  NumMax := 0;
  for j := 1 to VarArrayHighBound(vArr, 2) do begin
    Row := 0;
    for i := 1 to VarArrayHighBound(vArr, 1) do
      {Если данные являются числом, то обрабатываем их.
      Если элемент соответствует пустой ячейке, то VarType(VArr[i, j]) = varEmpty = 0.
      Если элемент соответствует ячейке с текстом, то VarType(VArr[i, j]) = varOleStr = 8}
      if VarType(VArr[i, j]) = varDouble then begin
        Inc(Row);
        Num := VArr[i, j];
        if Row = 1 then
          NumMax := Num
        else if Num > NumMax then
          NumMax := Num;
      end;
    if Row > 0 then
      Memo1.Lines.Add('Столбец: ' + IntToStr(j)
        + ', наибольшее: ' + FloatToStr(NumMax))
    else
      Memo1.Lines.Add('Столбец: ' + IntToStr(j)
        + ', в столбце нет числовых данных.');
  end;
end;
 
{Чтение данных с листа MS Excel в вариантный массив и
по-строчная обработка данных.}
procedure TForm1.Button2Click(Sender: TObject);
var
  exApp, exBook, exSh : Variant;
  VArr : Variant;
  i, j, Col : Integer;
  Num, NumMax : Extended;
  Od : TOpenDialog;
begin
  Od := OpenDialog1; //OpenDialog1 уже должен быть на форме.
  if Od.InitialDir = '' then
    Od.InitialDir := ExtractFilePath( ParamStr(0) );
  if not Od.Execute then Exit;
  if not FileExists(Od.FileName) then begin
    MessageBox(0, 'Файл с заданным именем не найден. Действие отменено.'
      ,'Файл не найден', MB_OK + MB_ICONEXCLAMATION + MB_APPLMODAL);
    Exit;
  end;
 
  //Попытка подключиться к корневому объекту MS Excel.
  try
    exApp := CreateOleObject('Excel.Application');
  except
    MessageBox(0, 'Не удалось запустить MS Excel. Действие отменено.',
      'Ошибка', MB_OK + MB_ICONERROR + MB_APPLMODAL);
    Exit;
  end;
  //Делаем видимым окно MS Excel. На время отладки или на постоянной основе.
  exApp.Visible := True;
  //Открываем файл рабочей книги.
  exBook := exApp.WorkBooks.Open(FileName:=Od.FileName);
  //Получаем ссылку на первый лист рабочей книги.
  exSh := exBook.Worksheets[1];
 
  {Получаем данные с листа рабочей книги MS Excel.
  Здесь предполагается, что верхняя левая ячейка в области данных
  на листе MS Excel имеет координаты: aRow = 5, aCol = 3,
  количество строк с данными: aCntRows = 3.}
  VArr := ExcelRowsToArr(exSh, 5, 3, 3);
  if VarIsClear(VArr) then begin
    MessageBox(0, 'На листе MS Excel нет данных. Действие отменено.',
      'Отмена', MB_OK + MB_ICONEXCLAMATION + MB_APPLMODAL);
    Exit;
  end;
 
  {Определяем наибольшее значение в каждой строке. Результаты записываем
  в Мемо.}
  Memo1.Clear;
  NumMax := 0;
  for i := 1 to VarArrayHighBound(vArr, 1) do begin
    Col := 0;
    for j := 1 to VarArrayHighBound(vArr, 2) do
      {Если данные являются числом, то обрабатываем их.
      Если элемент соответствует пустой ячейке, то VarType(VArr[i, j]) = varEmpty = 0.
      Если элемент соответствует ячейке с текстом, то VarType(VArr[i, j]) = varOleStr = 8}
      if VarType(VArr[i, j]) = varDouble then begin
        Inc(Col);
        Num := VArr[i, j];
        if Col = 1 then
          NumMax := Num
        else if Num > NumMax then
          NumMax := Num;
      end;
    if Col > 0 then
      Memo1.Lines.Add('Строка: ' + IntToStr(i)
        + ', наибольшее: ' + FloatToStr(NumMax))
    else
      Memo1.Lines.Add('Строка: ' + IntToStr(i)
        + ', в строке нет числовых данных.');
  end;
end;
 
end.
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
23.05.2013, 12:55
Помогаю со студенческими работами здесь

Delphi Поиск текста в Excel
Добрый день, я нуждаюсь в помощи с софтом. Cуть программы: Имеется приличного размера xls документ (ниже прикреплен аттач) ЛИСТ1...

Delphi 7 + Excel: Поиск по ячейкам
Есть огромный фаил .xlsx, с 58000+ строками Примерно как выглядит: А B C 4 1 текст 4 2 текст 7 1 текст ...

Быстрый поиск в Excel средствами Delphi
Добрый день уважаемые специалисты. Столкнулся с трудностью: Открываю файл Excel: Excel1:=CreateOleObject('Excel.Application'); ...

Delphi Как выполнить поиск в Excel
Помогите пожалуйста составить программу в Delphi. Нужна простая программа с поиском. дан файл в Excel. в поиске написать слова и программа...

БПФ, поиск максимума спектральной плотности, поиск экстремума (максимума) в отсчетах БПФ
Всем добра! В математике я нуб, нужна помощь в решение задачи в Matlab!!! Дано: 1) Частота дискретизации Fd=45000 Гц; 2) Кол-во...


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

Или воспользуйтесь поиском по форуму:
12
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Основы отладки веб-приложений на SDL3 по USB и Wi-Fi, запущенных в браузере мобильных устройств
8Observer8 07.02.2026
Содержание блога Браузер Chrome имеет средства для отладки мобильных веб-приложений по USB. В этой пошаговой инструкции ограничимся работой с консолью. Вывод в консоль - это часть процесса. . .
SDL3 для Web (WebAssembly): Обработчик клика мыши в браузере ПК и касания экрана в браузере на мобильном устройстве
8Observer8 02.02.2026
Содержание блога Для начала пошагово создадим рабочий пример для подготовки к экспериментам в браузере ПК и в браузере мобильного устройства. Потом напишем обработчик клика мыши и обработчик. . .
Философия технологии
iceja 01.02.2026
На мой взгляд у человека в технических проектах остается роль генерального директора. Все остальное нейронки делают уже лучше человека. Они не могут нести предпринимательские риски, не могут. . .
SDL3 для Web (WebAssembly): Вывод текста со шрифтом TTF с помощью SDL3_ttf
8Observer8 01.02.2026
Содержание блога В этой пошаговой инструкции создадим с нуля веб-приложение, которое выводит текст в окне браузера. Запустим на Android на локальном сервере. Загрузим Release на бесплатный. . .
SDL3 для Web (WebAssembly): Сборка C/C++ проекта из консоли
8Observer8 30.01.2026
Содержание блога Если вы откроете примеры для начинающих на официальном репозитории SDL3 в папке: examples, то вы увидите, что все примеры используют следующие четыре обязательные функции, а. . .
SDL3 для Web (WebAssembly): Установка Emscripten SDK (emsdk) и CMake для сборки C и C++ приложений в Wasm
8Observer8 30.01.2026
Содержание блога Для того чтобы скачать Emscripten SDK (emsdk) необходимо сначало скачать и уставить Git: Install for Windows. Следуйте стандартной процедуре установки Git через установщик. . . .
SDL3 для Android: Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 29.01.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами. Версия v3 была полностью переписана на Си, в. . .
Инструменты COM: Сохранение данный из VARIANT в файл и загрузка из файла в VARIANT
bedvit 28.01.2026
Сохранение базовых типов COM и массивов (одномерных или двухмерных) любой вложенности (деревья) в файл, с возможностью выбора алгоритмов сжатия и шифрования. Часть библиотеки BedvitCOM Использованы. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru