Сегодняшняя статья блога будет целиком посвящена работе с Excel Range или, говоря другими словами – работе с диапазонами ячеек Excel.
Про работу с этими объектами я уже вкратце говорил, а сегодня хотел бы поделиться с вами более полной информацией. Итак, начнем с самого простого. ' '
1. Что такое Range и как его получить?
Согласно официальному определению Microsoft, Range :
представляет собой ячейки, строки, столбцы, набор ячеек, содержащих один или более смежных блоков ячеек, или 3-D диапазон.
Однако это определение не исключает того, что объектом Range может выступать и одна ячейка (Cell) листа. Таким образом, чтобы получить в свое распоряжение объект Range, можно выполнить следующие операции c объектом Excel в Delphi:
var MyRange: OLEVariat;
begin
{объект Range, состоящий из одной ячейки}
MyRange:=MyExcel.ActiveWorkBook.ActiveWorkSheet.Range['A1'];
{объект Range в виде строки из четырех ячеек}
MyRange:=MyExcel.ActiveWorkBook.ActiveWorkSheet.Range['A1:D1'];
{объект Range в виде столбца из четырех ячеек}
MyRange:=MyExcel.ActiveWorkBook.ActiveWorkSheet.Range['A1:A4'];
{объект Range в виде таблицы 4х4 ячейки}
MyRange:=MyExcel.ActiveWorkBook.ActiveWorkSheet.Range['A1:D4'];
end;
Если Вам неудобно в какой-либо ситуации использовать буквенные обозначение ячеек или Вы привыкли до этого момента иметь дело только с отдельными ячейками (Cells), то объект Range можно получить например вот так:
var MyRange: OLEVariat;
Cell_1, Cell2: OLEVariant;
begin
{получаем ссылку на объект Cells, соответствующей ячейке A1}
Cell_1:=MyExcel.ActiveWorkBook.ActiveWorkSheet.Cells[1,1];
{получаем ссылку на объект Cells, соответствующей ячейке C5}
Cell_2:=MyExcel.ActiveWorkBook.ActiveWorkSheet.Cells[5,3];
{получаем объект Range размером 3х5}
MyRange:=MyExcel.ActiveWorkBook.ActiveWorkSheet.Range[Cell_1, Cell_2]
end;
Какой из способов Вы будите использовать в Delphi – не важно, так как результат будет один и тот же.
2. Свойства объекта Excel Range.
Рассмотрим основные свойства объекта Range и их применение работе в Excel в Delphi.
Formula
Возвращает или помещает в диапазон формулу.
Value
Возвращает или устанавливает значение для диапазона.Свойство Value замечательно тем, что с помощью него можно записать в ячейки абсолютно любые данные, особо не задумываясь о формате данных. Например, запишем в ячейки диапазона строку, число типа integer и число типа single: чтобы каждый раз не повторяться в листингах и не писать одни и те же элементы по 100 раз, будем считать, что в переменной Sheet уже содержится ссылка на активный лист (ActiveWorkSheet) активной книги (ActiveWorkBook) Excel (MyExcel)
var i:integer;
s: single;
str: string;
Sheet: OLEVariant;
begin
i:=100;
s:=2.12;
str:='Hello World!';
Sheet.Range['A1'].Value:=i;
Sheet.Range['A2'].Value:=s;
Sheet.Range['A3'].Value:=str;
end;
Как видите, обращение к ячейкам было одно и то же и нигде я не приводил данный к какому-то типу – записал в ячейки всё как есть.
Если Вы хотите записать в весь диапазон Range одно и то же значение, то просто выполните:
Sheet.Range['A1:A10'].Value:=str;
и получите одну и ту же строку “Hello World!” в десяти ячейках Excel, но такие операции очень редко необходимы при работе с Excel в Delphi. Зато очень часто необходимо воспользоваться другой стороной свойства Value - прочитать большой объем данных из книги Excel за один прием и получить весь массив данных в Delphi. Операция чтения данных из Excel в Delphi более проста, чем Вам может показаться на первый взгляд. Проведем обратную операцию – прочитаем данные из Excel:
var val: Variant;
Sheet: OLEVariant;
i:integer;
begin
Val:=Sheet.Range['A1:A3'].Value;
for i:=1 to 3 do
ShowMessage(val[i,1]);
end;
Как видите здесь мы за один прием прочитали данные сразу из трех ячеек Excel и отобразили их в сообщении. Этот прием чтения на порядок более скоростной, чем, например чтение содержимого каждой ячейки (Cells) в отдельности.
Text
Ещё одно простенькое свойство объекта Range - возвращает текст из ячейки. Самое главное отличие от свойства Value - Text возвращает string только для чтения и использовать это свойство для чтения большого объема данных, как в предыдущем примере – ни в коем случае нельзя, т.к. переменная Val вернет значение Null.
Column
Возвращает номер первого столбца в первой области, в указанном диапазоне. Свойство только для чтения.
Чтобы продемонстрировать свойство в действии, давайте создадим такие диапазоны как показано на рисунке:
То есть каждый из диапазонов Range будет содержать по две несвязанные друг с другом области (Area). Причем первая область диапазона Range будет начинаться в столбце А, а первая область второго диапазона (Range 2) – в столбце B.
После того, как диапазоны будут созданы – посмотрим, что вернет нам свойство Column для каждого из диапазонов.
Листинг процедуры создания двух несвязных диапазонов Range следующий:
var Range1,Range2,BigRange: OLEVariant;
begin
{создаем первый диапазон}
Range1:=Sheet.Range['A1:C4'];
Range2:=Sheet.Range['E6:H9'];
BigRange:=Sheet.Range[Range1,Range2];
ShowMessage(IntToStr(BigRange.Column)); //показываем значение свойства
{создаем второй диапазон}
Range1:=Sheet.Range['B7:C13'];
Range2:=Sheet.Range['E1:H3'];
BigRange:=Sheet.Range[Range1,Range2];
ShowMessage(IntToStr(BigRange.Column)); //показываем значение свойства
end;
Так, в случае с первым Range Column вернет нам значение 1, а для второго Range - значение 2.
Columns
В отличие от предыдущего свойства, Columns возвращает не простое число, а объект Range, представляющий собой один столбец из всего диапазона.
Посмотрим как, например, используя это свойство можно изменять столбцы во всем диапазоне Range.
Для демонстрации воспользуемся предыдущим примером, изменим только окончание:
... BigRange:=Sheet.Range[Range1,Range2]; for i:=1 to BigRange.Columns.Count do BigRange.Columns[i].Value:='Столбец №'+IntToStr(i);
В итоге в каждый из столбцов диапазона должна записаться строка с номером этого столбца, результат представлен на рисунке. Как видите, в цикле все столбцы обработались “насквозь”, хотя Range не содержал в себе столбец D.
Comment
Возвращает объект Comment для Range. В данном случае Range должен определять одну ячейку.
Для демонстрации свойства не будем заходить в Excel, поработаем с приложением прямо из Delphi. Для этого воспользуемся методом AddComment. То есть сначала запишем комментарий в ячейку, а потом прочитаем его используя свойство Comment:
Range2:=Sheet.Range['E6'];
{записали комментарий}
Range2.AddComment('Это комментарий ячейки области');
{прочитали}
ShowMessage(Range2.Comment.Text);
Address
Возвращает реальный адрес диапазона Range. Например для диапазона ячеек, заданных вот таким образом:
Range2:=Sheet.Range['A1:E6']; Свойство Address будет содержать строку "$A$1:$E$6"
Это свойство удобно использовать, когда Вы оперируете в программе только числовыми значениями (номерами столбцов и строк) и появляется необходимость показать пользователю адреса ячеек из диапазона.
Помимо перечисленных выше свойств к объекту Range применимы все свойства, описанный в статье об изменении внешнего вида ячеек Excel, т.е. borders, color и пр.
3. Методы объекта Excel Range.
Теперь рассмотрим несколько полезных методов, которые могут Вам пригодиться при работе с Excel в Delphi.
CheckSpelling
Проверяет грамматику в выдранном диапазоне и при нахождении ошибок выводит окно для замены. Замечательной особенностью этого метода является то, что окно замены появляется даже при скрытом окне Excel, т.е. когда свойство Visible у объекта Excel равно false.
Вызывается метод без каких-либо дополнительных параметров:
Range['A1:H6'].CheckSpelling
PrintPreview
Выводит на экран окно предварительного просмотра перед печатью выбранного диапазона ячеек. Также как и предыдущий метод PrintPreview не имеет дополнительных параметров. Однако при попытке вызвать метод при скрытом окне Excel в лучшем случае возникнет исключительная ситуация, в худшем – зависание Вашего приложения. Так что перед вызовом:
MyRange.PrintPreview
не забывайте включить свойство Visible у Excel:
MyExcel.Visible:=true;
AutoFill
Автозаполнение диапазона ячеек на основе данных из другого диапазона.
Вызов метода: Range.AutoFill(Destination, Type)
Destination - представляет собой объект Range уже заполненных ячеек. Эти ячейки должны входить в автозаполняемый диапазон.
Type - тип автозаполнения.
Рассмотрим применение метода на примере.
Sheet.Range['A1'].Value:=1; Sheet.Range['A2'].Value:=2; Source:=Sheet.Range['A1:A6']; Range2:=Sheet.Range['A1:E6']; Source.AutoFill(Range2, xlFillDefault)
В результате лист Excel примет следующий вид:
Как видите все столбцы второго диапазона Range заполнились значениями из диапазоны Source.
При использовании этого метода следует иметь в виду, что диапазон-источник (в нашем случае – это source) по одному из измерений должен совпадать с источником назначения. В приведенном примере совпадает размерность по строкам (в обоих диапазонах их шесть). Если размерности диапазонов не совпадают, то возникает исключительная ситуация.
При использовании метода мы использовали одну из констант в параметре Type - xlFillDefault = 0. Используя её мы скопировали данные один-к-одному. Дополнительно Вы можете использовать следующие константы при автозаполнении:
xlFillDays = 5 – копирование дней недели с расширением, т.е., если Вы запишете в ячейку слово “Понедельник” и попробуете провести автозаполнение ещё на 2 строки, то во второй и третьей строке появятся “Вторник” и “Среда”
xlFillCopy = 1 – копирует все данные и форматы, повторяя при необходимости
xlFillFormats = 3 – копирует только форматы источника
xlFillMonths = 7 – копирует названия месяцев. Работает аналогично xlFillDays
xlFillSeries = 2 – копирует данные с расширением, например 1,2,3 будут при копировании расширены до 4,5,6 и т.д. Также копирует форматы данных.
xlFillValues = 4 – копирует только значения
xlFillWeekdays = 6 – копирует дни рабочей недели, работает аналогично xlFillDays, но только до пятницы.
xlFillYears = 8 – копирует года. Работает аналогично xlFillDays.
xlGrowthTrend = 10 – копирует числовые значения из источника, расширяя их в предположении, что каждое последующее число представляет собой предыдущее, но умноженное на некоторую величину. Например 1,2 раскопируются в 4, 8, 16 и т.д. Формат данных также копируется.
xlLinearTrend = 9 – копирует числовые значения из источника, расширяя их в предположении, что каждое последующее число представляет собой предыдущее + некоторая величина. Например 1,2 раскопируются в 3, 4, 5 и т.д. Формат данных также копируется.
AutoFit
Изменяет ширину или высоту ячеек диапазона для наилучшего представления данных.
Пример вызова:
Sheet.Range['A1'].Value:=1234567891012; Sheet.Range['A2'].Value:=23456789; Source:=Sheet.Range['A1:A2']; Source.Columns.AutoFit
Приведет и изменению ширины столбца А таким образом, чтобы число было полностью видно на листе.
Методы очистки данных диапазона Range
Есть несколько различных методов очистки содержимого диапазона Range при работе с Excel в Delphi.
1. Clear
Удаляет все данные из диапазона.
Пример вызова:
MyRange.Clear
2. ClearComments
Удаляет все комментарии в диапазоне Range.
Пример вызова:
MyRange.ClearComments
3. ClearContents
Удаляет все формулы из диапазона Range
Пример вызова:
MyRange.ClearContents
4. ClearFormats
Очищает форматы в диапазоне Range
Пример вызова:
MyRange.ClearFormats
5. ClearNotes
Очищает все заметки в диапазоне Range
Пример вызова:
MyRange.ClearNotes
Методы работы с буфером обмена Excel
1. Copy
Копирует содержимое диапазона Range в буфер обмена или в другой диапазон.
Попробуем реализовать работу метода следующим образом: заполним столбец А некоторыми значениями, а затем скопируем его сначала в буфер, а потом в столбец Е:
Sheet.Range['A1'].Value:=1; Sheet.Range['A2'].Value:=2; Sheet.Range['A3'].Value:=3; Sheet.Range['A4'].Value:=4; Sheet.Range['A5'].Value:=5; Sheet.Range['A6'].Value:=6; Source:=Sheet.Range['A1:A6']; Source.Copy; //скопировали в буфер Range2:=Sheet.Range['E1:E6']; Source.Copy(Range2)//скопировали в новый диапазон
А для того, чтобы вставить данные из буфера обмена существует ещё один метод
2. PasteSpecial
Вызов метода:
MyRange.PasteSpecial(Paste, Operation, SkipBlanks, Transpose)
Paste – определяет какая часть данных диапазона будет вставлена. При определении этого параметра следует использовать следующие константы:
| xlPasteAll | -4104 | Вставка всех данных |
| xlPasteAllExceptBorders | 7 | Вставка всего содержимого за исключением вида границ диапазона |
| xlPasteAllUsingSourceTheme | 13 | Вставка всего содержимого, используя тему оформления источника |
| xlPasteColumnWidths | 8 | Копирует ширину столбцов |
| xlPasteComments | -4144 | Вставка комментариев |
| xlPasteFormats | -4122 | Вставка форматов данных |
| xlPasteFormulas | -4123 | Вставка формул |
| xlPasteFormulasAndNumberFormats | 11 | Вставка формул и чисел |
| xlPasteValidation | 6 | Вставка проверок |
| xlPasteValues | -4163 | Вставка значений |
| xlPasteValuesAndNumberFormats | 12 | Вставка значений и чисел |
Operation - операция, которая будет выполнена при вставке данных. При использовании параметра следует использовать следующие константы:
| xlPasteSpecialOperationAdd | 2 | К скопированным данным будут добавлены значения из целевых ячеек |
| xlPasteSpecialOperationDivide | 5 | Скопированные данные будут разделены на значения в целевых ячейках |
| xlPasteSpecialOperationMultiply | 4 | Скопированные данные будут умножены на значения в целевых ячейках |
| xlPasteSpecialOperationNone | -4142 | При вставке значений никакие операции не будут применяться |
| xlPasteSpecialOperationSubtract | 3 | Из скопированных данных будут вычитаться значения целевых ячеек |
SkipBlanks - True, для того чтобы пустые ячейки из буфера обмена не вставлялись в диапазон назначения. Значение по умолчанию False.
Transpose - транспонирование столбцов и строк после вставки. По умолчанию устанавливается значение False.
Теперь рассмотрим применение метода на примере. В качестве исходных данных возьмем данные из предыдущего примера, но для вставки используем метод PasteSpecial:
... Range2.PasteSpecial(Operation:=xlPasteSpecialOperationAdd);
После выполнения этой операции все данные вставятся в диапазон Range2, т.к. диапазон до вставки был пуст, то данные скопировались один-к-одному.
3. Cut
Вырезает данные и при необходимости вставляет их в новый диапазон. Метод работает аналогично методу Copy, но с последующим удалением данных из источника.
Merge
Объединение ячеек диапазона.
Для новичков, только начинающих постигать азы работы с excel в Delphi этот метод в какой-то момент становится камнем преткновения :). Дело в том, что очень часто возникает необходимость объединить часть ячеек листа для записи в объединенную область большого количества данных или длинной строки. В Excel есть такой метод Union, который и отвечает за объединение – им-то и пробуют пользоваться многие. А метод Union при вызове из Delphi применительно к диапазону Range вызывает исключительную ситуацию. Про Merge люди либо не знают, либо забывают. А использовать его достаточно просто:
Range.Merge(Across)
Across - True, чтобы объединить ячейки в каждой строке указанного диапазона как отдельные объекты. Значение по умолчанию False.
Например, объединим ячейки в диапазоне Range2 из предыдущего примера:
Range2.Merge;
После выполнения этой операции в диапазоне останется только верхнее значение, т.е. 1.
Дополнительные методы автозаполнения ячеек диапазона Range
В отдельную группу методов можно выделить 4 метода автозаполнения ячеек диапазона:
- FillDown
- FillUp
- FillRight
- FillLeft
Принцип действия этих методов один и тот же за исключением направления автозаполнения.
Например, давайте запишем в ячейку A1 какое-нибудь значение и воспользуемся методами FillDown и FillRight:
Sheet.Range['A1'].Value:=1; Sheet.Range['A1:A6'].FillDown; Sheet.Range['A1:F1'].FillRight;
После этого в строк 1 и столбце A появятся числа 1. Аналогичным образом можно заполнять не только строки или столбцы, но и таблицы целиком – достаточно знать в какую сторону двигаться при автозаполнениии и применять соответствующие методы Excel для Range.
Вот в принципе краткий обзор возможностей работы с объектов Range в Excel. В целом можно отметить, что работа с этим объектом в Delphi один из самых эффективных способов организации пресылки/получения данных между Excel и Delphi, не считая работы через XML формат. Ну, а пока Вы постигаете основы работы с объектами Range, я продолжу работы над проектом “Блевантон”, а также попробую решить одну далеко не тривиальную задачу- получить объект диаграммы Excel вставленной в Word :) Надеюсь смогу решить, а пока потрещё в аське со знатоками этого дела. Кстати, скачать аську можно на ICQTrust.ru.
Мой блог находят по следующим фразам
- delphi excel толщина линий
- Обновленная справка для delphi 2009
- delphi excel лист активным
- Excel открыть объект Word
- php очистка html
- использование mlang.dll
Related posts:










22 Sep 2009 в 6:54 am
Свойства Text и Value не позволяют получить текст даже одной печатной страницы…
Неужели для получения большого объёма текста листа нужно использовать только буфер обмена? Имею в виду, что вначале выделить данные, потом методом Copy скопировать в буфер, а далее стандартными средствами Delphi изъять текст.
22 Sep 2009 в 7:08 am
Почему не позволяют? Оба свойства на сколько мне помнится read/write. Другое дело, что ОЧЕНЬ медленно читать текст большого объема. Я обычно работаю с большими таблицами, причём форматированными по-разному, т.е. смысл и содержание одно, а формат разный – всегда копирую в вариантный массив по столбцам – так проще в случае чего сопоставлять данные в таблице. А вообще есть вариант, как говорят, ещё более скоростной – обмен через XML, но я им никогда не пользовался, поэтому сказать что он круче, лешче и т.д. не могу :)
15 Nov 2009 в 1:58 pm
А можно немного рассказать об методе Characters объекта Range? Столкнулся с такой проблеммой нужно было из базы делать экспорт в Excel (несколько Абревеатур в одну строчку, через запятую ) и раскрашивать эти абревеатуры чветом в зависомости от статуса этой абревиатуры. При выгрузке после добавления новой строчки строка обрабатывалась: находился начальный символ в стрке через Pos и затем длинна выгружаемого значания. Затем Pos1 и Pos2 – начало диапозона и длинна передавались свойству Active.Cells.Charactres (pos1,pos2).Font.Color:= в зависимости от значения выгрузки. Так вот, при выгрузке 2х значений все нармуль, только выгружаю 3-е все раскраска сбивается… Может кто подскажет в чем может быть проблемма?
TMainForm.Excel1Click(Sender: TObject); // экспорт отчета в Excel
var
E,Range:Variant;
i,j,k:Integer;
pos1,pos2:OleVariant;
S,s1:String;
begin
Dm.ExportQuery.Active:=True;
Dm.ExportQuery.First;
// получаем объект Excel//
E:=CreateOleObject ('Excel.Application');
E.Application.EnableEvents:= false;
E.DisplayAlerts := False; // Discard unsaved files....
E.WorkBooks.Add(ExtractFilePath(Application.ExeName)+'Shablons\Rep.xls');
SGauge1.Visible:=True;
SGauge1.MaxValue:=Dm.ExportQuery.RecordCount-1;
for i := 0 to Dm.ExportQuery.RecordCount-1 do
begin
// вставляем данные по тренерам + доп данные и раскрашиваем ячейки
E.Workbooks[1].WorkSheets[1].Cells[i+2,1]:=IntToStr(i+1);
E.Workbooks[1].WorkSheets[1].Cells[i+2,2]:=Dm.ExportQuery.FieldByName('Fio').AsString;
if dm.ExportQuery.FieldByName ('Stat').Asstring='Временно пониженный'
then
begin
E.Workbooks[1].WorkSheets[1].Cells[i+2,2].interior.ColorIndex:=36;
end;
if dm.ExportQuery.FieldByName ('Stat').Asstring ='Вр. сетртифицирован'
then
begin
E.Workbooks[1].WorkSheets[1].Cells[i+2,2].interior.ColorIndex:=37;
end;
if dm.ExportQuery.FieldByName ('Stat').Asstring ='Отстранен от работы'
then
begin
E.Workbooks[1].WorkSheets[1].Cells[i+2,2].interior.ColorIndex:=48;
end;
E.Workbooks[1].WorkSheets[1].Cells[i+2,3]:=Dm.ExportQuery.FieldByName('BDate').AsString;
E.Workbooks[1].WorkSheets[1].Cells[i+2,4]:=Dm.ExportQuery.FieldByName('Adr').AsString;
E.Workbooks[1].WorkSheets[1].Cells[i+2,5]:=Dm.ExportQuery.FieldByName('tel').AsString+
Char(10)+Dm.ExportQuery.FieldByName('tel2').AsString+Char(10)+Dm.ExportQuery.FieldByName('Sot_tel').AsString;
E.Workbooks[1].WorkSheets[1].Cells[i+2,6]:='Email:'+Dm.ExportQuery.FieldByName('EMail').AsString+
Char(10)+'SkyPee:'+Dm.ExportQuery.FieldByName('SkyPee').AsString+Char(10)+'ICQ:'+Dm.ExportQuery.FieldByName('ICQ').AsString;
//записывваем курсы ....
Dm.ExportQuery2.ParamByName('Tr_param').AsInteger:=Dm.ExportQuery.FieldByName ('Tr_Id').AsInteger;
Dm.ExportQuery2.Active:=True;
Dm.ExportQuery2.First;
for j := 0 to Dm.ExportQuery2.RecordCount-1 do
begin
E.Workbooks[1].WorkSheets[1].Cells[i+2,7]:=E.Workbooks[1].WorkSheets[1].Cells[i+2,7].Text+Dm.ExportQuery2.FieldByName('KursName').AsString+',';
// раскраска части текста в ячейке
if Dm.ExportQuery2.FieldByName('KursStat').AsString='Понижен' then
begin
Pos1:=0;
Pos2:=0;
Pos1:=Pos(Dm.ExportQuery2.FieldByName('KursName').AsString,E.Workbooks[1].WorkSheets[1].Cells[i+2,7].Text);
Pos2:=Length(Dm.ExportQuery2.FieldByName('KursName').AsString);
E.Workbooks[1].WorkSheets[1].Cells[i+2,7].Characters[pos1,pos2].Font.Colorx:=5;
end;
if Dm.ExportQuery2.FieldByName('KursStat').AsString='Отстранен' then
begin
Pos1:=0;
Pos2:=0;
Pos1:=Pos(Dm.ExportQuery2.FieldByName('KursName').AsString,E.Workbooks[1].WorkSheets[1].Cells[i+2,7].Text);
Pos2:=Length(Dm.ExportQuery2.FieldByName('KursName').AsString);
E.Workbooks[1].WorkSheets[1].Cells[i+2,7].Characters[pos1,pos2].Font.ColorIndex := 6;
end;
if Dm.ExportQuery2.FieldByName('KursStat').AsString='Вренеммно сетр-ван' then
begin
Pos1:=0;
Pos2:=0;
Pos1:=Pos(Dm.ExportQuery2.FieldByName('KursName').AsString,E.Workbooks[1].WorkSheets[1].Cells[i+2,7].Text);
Pos2:=Length(Dm.ExportQuery2.FieldByName('KursName').AsString);
E.Workbooks[1].WorkSheets[1].Cells[i+2,7].Characters[pos1, pos2].Font.ColorIndex := 7;
end;
if Dm.ExportQuery2.FieldByName('KursStat').AsString='Временно установлен' then
begin
Pos1:=0;
Pos2:=0;
Pos1:=Pos(Dm.ExportQuery2.FieldByName('KursName').AsString,E.Workbooks[1].WorkSheets[1].Cells[i+2,7].Text);
Pos2:=Length(Dm.ExportQuery2.FieldByName('KursName').AsString);
E.Workbooks[1].WorkSheets[1].Cells[i+2,7].Characters[pos1, pos2].Font.ColorIndex :=8;
end;
if Dm.ExportQuery2.FieldByName('KursStat').AsString='Нормальный' then
begin
Pos1:=0;
Pos2:=0;
Pos1:=Pos(Dm.ExportQuery2.FieldByName('KursName').AsString,E.Workbooks[1].WorkSheets[1].Cells[i+2,7].Text);
Pos2:=Length(Dm.ExportQuery2.FieldByName('KursName').AsString);
E.Workbooks[1].WorkSheets[1].Cells[i+2,7].Characters[pos1, pos2].Font.ColorIndex:=10;
end;
// распихиваем по статусу тренера в курсе
if Dm.ExportQuery2.FieldByName('TrStatForKurs').AsString='Тренер-стажер' then
begin
E.Workbooks[1].WorkSheets[1].Cells[i+2,8]:=E.Workbooks[1].WorkSheets[1].Cells[i+2,8].Text+''+Dm.ExportQuery2.FieldByName('KursName').AsString+' ';
end;
if Dm.ExportQuery2.FieldByName('TrStatForKurs').AsString='Тренер' then
begin
E.Workbooks[1].WorkSheets[1].Cells[i+2,9]:=E.Workbooks[1].WorkSheets[1].Cells[i+2,9].Text+''+Dm.ExportQuery2.FieldByName('KursName').AsString+' ';
end;
if Dm.ExportQuery2.FieldByName('TrStatForKurs').AsString='Старший тренер' then
begin
E.Workbooks[1].WorkSheets[1].Cells[i+2,10]:=E.Workbooks[1].WorkSheets[1].Cells[i+2,10].Text+''+Dm.ExportQuery2.FieldByName('KursName').AsString+' ';
end;
if Dm.ExportQuery2.FieldByName('TrStatForKurs').AsString='Ведущий тренер корпорации' then
begin
E.Workbooks[1].WorkSheets[1].Cells[i+2,11]:=E.Workbooks[1].WorkSheets[1].Cells[i+2,11].Text+''+Dm.ExportQuery2.FieldByName('KursName').AsString+' ';
end;
//Добавляем прмечание
if Dm.ExportQuery2.FieldByName ('Prim').AsString<>'' then
begin
E.Workbooks[1].WorkSheets[1].Cells[i+2,12]:=E.Workbooks[1].WorkSheets[1].Cells[i+2,12].Text+
Dm.ExportQuery2.FieldByName('KursName').AsString+':'+Dm.ExportQuery2.FieldByName('Prim').AsString+' ';
end;
Pos1:=0;
Pos2:=0;
Dm.ExportQuery2.Next;
end;
Dm.ExportQuery2.Active:=False;
Sgauge1.Progress:=Sgauge1.Progress+1;
dm.ExportQuery.Next;
// k:=k+1;
end;
Dm.ExportQuery.Active:=False;
Sgauge1.Visible:=False;
E.Workbooks[1].SaveAs (ExtractFilePath(Application.ExeName)+'out_excel\'+'Report_'+''''+FormatDateTime('dd.mm.yyyy',Now())+'''');
E.Visible:=True;
E:= Unassigned;
end;
15 Nov 2009 в 6:01 pm
Расскажите, пожалуйста немного по-подробнее как сбивается работа программы? Возникает исключительная ситуация? Просто не так как надо раскрашивается? Если ошибка, то желательно текст ошибки тоже показать – так будет проще разобраться как решить вашу проблему.
15 Nov 2009 в 6:32 pm
Спасибо что откликнулись. Проблемма такого плана:
допустим есть у тренера 3 курса:
PL BYB MF
со статусами : понижен, отстранен, нормальный соответственно.
При выгрузке ни IDE ни Excel не ругается, сама выгрузка проходит, НО
получается если 2 курса то все нармально , цвета корректно присваиваются, если больше 2 то тут начинается следующие:
первый курс и все последующие,за исключением последнего (ему присваивается правельный цвет), получают значение цвета первого курса, почему не могу понять….
При отладке программы отслеживал pos1 и pos2 значения всегда верные, как видно из кода даже попробовал их обнулять принудительно (хотя это полный бред) но все без результатно…. Вот такая вот загогулина
16 Nov 2009 в 12:13 am
Понятно. Попробую написать небольшой примерчик. Думаю, что получится :)
31 Aug 2010 в 1:57 pm
У меня ругается на Unit4.MyExcel.ActiveWorkBook.ActiveWorkSheet.range[1,2].value:=’jkjh’;
такую строку. Говорит что ActiveWorkSheet “Not supported by automation object” как это побороть?