Delphi excel буфер обмена

уважаемые посетители блога, если Вам понравилась, то, пожалуйста, помогите автору с лечением. Подробности тут.

Сегодняшняя статья блога  будет целиком посвящена работе с Excel Range или, говоря другими словами — работе с диапазонами ячеек Excel.

Про работу с этими объектами я уже вкратце говорил, а сегодня хотел бы поделиться с вами более полной информацией. Итак, начнем с самого простого.

1. Что такое Range и как его получить?

Согласно официальному определению Microsoft, Range :

представляет собой ячейки, строки, столбцы, набор ячеек, содержащих один или более смежных блоков ячеек, или 3-D диапазон.

Однако это определение не исключает того, что объектом Range может выступать и одна ячейка (Cell) листа.  Таким образом, чтобы получить в свое распоряжение объект Range, можно выполнить следующие операции c объектом Excel в Delphi:

var  MyRange: OLEVariat;
begin
{объект Range, состоящий из одной ячейки}
  MyRange:=MyExcel.ActiveWorkBook.ActiveSheet.Range['A1'];
{объект Range в виде строки из четырех ячеек}
  MyRange:=MyExcel.ActiveWorkBook.ActiveSheet.Range['A1:D1'];
{объект Range в виде столбца из четырех ячеек}
  MyRange:=MyExcel.ActiveWorkBook.ActiveSheet.Range['A1:A4'];
{объект Range в виде таблицы 4х4 ячейки}
  MyRange:=MyExcel.ActiveWorkBook.ActiveSheet.Range['A1:D4'];
end;

Если Вам неудобно в какой-либо ситуации использовать буквенные обозначение ячеек или Вы привыкли до этого момента иметь дело только с отдельными ячейками (Cells), то объект Range можно получить например вот так:

var  MyRange: OLEVariat;
     Cell_1, Cell2: OLEVariant;
begin
{получаем ссылку на объект Cells, соответствующей ячейке A1}
  Cell_1:=MyExcel.ActiveWorkBook.ActiveSheet.Cells[1,1];
{получаем ссылку на объект Cells, соответствующей ячейке C5}
  Cell_2:=MyExcel.ActiveWorkBook.ActiveSheet.Cells[5,3];
{получаем объект Range размером 3х5}
  MyRange:=MyExcel.ActiveWorkBook.ActiveSheet.Range[Cell_1, Cell_2]
end;

Какой из способов Вы будете использовать в Delphi — не важно, так как результат будет один и тот же. Получив в свое распоряжение диапазон Вы можете использовать его далее, например, для того, чтобы установить вид его границ.

2. Свойства объекта Excel Range.

Рассмотрим основные свойства объекта Range и их применение работе в Excel в Delphi.

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

Свойство Описание
Formula Возвращает или помещает в диапазон формулу
Value Возвращает или устанавливает значение для диапазона
Text возвращает текст из ячейки
Column Возвращает номер первого столбца в первой области, в указанном диапазоне
Columns возвращает объект Range, представляющий собой один столбец из всего диапазона
Comment Возвращает объект Comment для Range. В данном случае Range должен определять одну ячейку.
Address Возвращает реальный адрес диапазона Range

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 в Delphi рассказывается в статье «Быстрая обработка данных Excel в Delphi.«

Как видите здесь мы за один прием прочитали данные сразу из трех ячеек Excel и отобразили их в сообщении. Этот прием чтения на порядок более скоростной, чем, например чтение содержимого каждой ячейки (Cells) в отдельности.

Text

Ещё одно простенькое свойство объекта Range — возвращает текст из ячейки. Самое главное отличие от свойства Value Text возвращает string только для чтения и использовать это свойство для чтения большого объема данных, как в предыдущем примере — ни в коем случае нельзя, так как переменная Val вернет значение Null.

Column

Возвращает номер первого столбца в первой области, в указанном диапазоне. Свойство только для чтения.

Чтобы продемонстрировать свойство в действии, давайте создадим такие диапазоны как показано на рисунке:

Excel_RangeТо есть каждый из диапазонов 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);

Excel_Range_ColumnsВ итоге в каждый из столбцов диапазона должна записаться строка с номером этого столбца, результат представлен на рисунке. Как видите, в цикле все столбцы обработались «насквозь», хотя Range не содержал в себе столбец D.

Возвращает объект 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 Проверяет грамматику в выбранном диапазоне и при нахождении ошибок выводит окно для замены
PrintPreview Выводит на экран окно предварительного просмотра перед печатью выбранного диапазона ячеек
AutoFill Автозаполнение диапазона ячеек на основе данных из другого диапазона
AutoFit Изменяет ширину или высоту ячеек диапазона для наилучшего представления данных.
Clear Удаляет все данные из диапазона
ClearComments Удаляет все комментарии в диапазоне Range
ClearContents Удаляет все формулы из диапазона Range
ClearFormats Очищает форматы в диапазоне Range
ClearNotes Очищает все заметки в диапазоне Range
Copy Копирует содержимое диапазона Range в буфер обмена или в другой диапазон
PasteSpecial Специальная вставка диапазона
Cut Вырезает данные и при необходимости вставляет их в новый диапазон
Merge Объединение ячеек диапазона

CheckSpelling

Проверяет грамматику в выбранном диапазоне и при нахождении ошибок выводит окно для замены. Замечательной особенностью этого метода является то, что окно замены появляется даже при скрытом окне Excel, то есть, когда свойство Visible у объекта Excel равно false.

Вызывается метод без каких-либо дополнительных параметров:

Range['A1:H6'].CheckSpelling

PrintPreview

Выводит на экран окно предварительного просмотра перед печатью выбранного диапазона ячеек. Также как и предыдущий метод PrintPreview не имеет дополнительных параметров. Однако при попытке вызвать метод при скрытом окне Excel в лучшем случае возникнет исключительная ситуация, в худшем — зависание Вашего приложения. Так что перед вызовом:

не забывайте включить свойство Visible у Excel:

AutoFill

Автоматическое заполнение диапазона ячеек на основе данных из другого диапазона.

Вызов метода:

Range.AutoFill(Destination, Type)
Параметр Тип Описание
Destination Variant представляет собой объект Range уже заполненных ячеек. Эти ячейки должны входить в автозаполняемый диапазон
Type Integer тип автозаполнения (возможные значения см. ниже)

Рассмотрим применение метода на примере.

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 примет следующий вид:

Excel_Range_AutoFillКак видите все столбцы второго диапазона Range заполнились значениями из диапазоны Source.

При использовании этого метода следует иметь в виду, что диапазон-источник (в нашем случае — это source) по одному из измерений должен совпадать с источником назначения. В приведенном примере совпадает размерность по строкам (в обоих диапазонах их шесть). Если размерности диапазонов не совпадают, то возникает исключительная ситуация.

При использовании метода мы использовали одну из констант в параметре Type xlFillDefault = 0. Используя её мы скопировали данные один-к-одному. Дополнительно Вы можете использовать следующие константы при автозаполнении:

Имя Значение Описание
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

Удаляет все данные из диапазона.

Пример вызова:

2. ClearComments

Удаляет все комментарии в диапазоне Range.

Пример вызова:

3. ClearContents

Удаляет все формулы из диапазона Range

Пример вызова:

4. ClearFormats

Очищает форматы в диапазоне Range

Пример вызова:

5. ClearNotes

Очищает все заметки в диапазоне Range

Пример вызова:

Методы работы с буфером обмена 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 Integer определяет какая часть данных диапазона будет вставлена (возможные значения см. ниже)
Operation Integer операция, которая будет выполнена при вставке данных (возможные значения см. ниже)
SkipBlanks boolean True, для того чтобы пустые ячейки из буфера обмена не вставлялись в диапазон назначения. Значение по умолчанию False
Transpose boolean транспонирование столбцов и строк после вставки. По умолчанию устанавливается значение False

При определении параметра 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 Из скопированных данных будут вычитаться значения целевых ячеек

Теперь рассмотрим применение метода на примере. В качестве исходных данных возьмем данные из предыдущего примера, но для вставки используем метод PasteSpecial:

...
Range2.PasteSpecial(Operation:=xlPasteSpecialOperationAdd);

После выполнения этой операции все данные вставятся в диапазон Range2, т.к. диапазон до вставки был пуст, то данные скопировались один-к-одному.

3. Cut

Вырезает данные и при необходимости вставляет их в новый диапазон. Метод работает аналогично методу Copy, но с последующим удалением данных из источника.

Merge

Объединение ячеек диапазона.

Для новичков, только начинающих постигать азы работы с excel в Delphi этот метод в какой-то момент становится камнем преткновения :). Дело в том, что очень часто возникает необходимость объединить часть ячеек листа для записи в объединенную область большого количества данных или длинной строки. В Excel есть такой метод Union, который и отвечает за объединение — им-то и пробуют пользоваться многие. А метод Union при вызове из Delphi применительно к диапазону Range вызывает исключительную ситуацию. Про Merge люди либо не знают, либо забывают. А использовать его достаточно просто:

Параметр Тип Описание
Across boolean True, чтобы объединить ячейки в каждой строке указанного диапазона как отдельные объекты. Значение по умолчанию False

Например, объединим ячейки в диапазоне Range2 из предыдущего примера:

После выполнения этой операции в диапазоне останется только верхнее значение, т.е. 1.

Дополнительные методы автозаполнения ячеек диапазона Range

В отдельную группу методов можно выделить 4 метода автозаполнения ячеек диапазона:

  1. FillDown
  2. FillUp
  3. FillRight
  4. 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 формат.

Книжная полка

Название:Разработка приложений Microsoft Office 2007 в Delphi

Описание Описаны общие подходы к программированию приложений MS Office. Даны программные методы реализации функций MS Excel, MS Word, MS Access и MS Outlook в среде Delphi.

купить книгу delphi на ЛитРес

0
0
голоса

Рейтинг статьи

уважаемые посетители блога, если Вам понравилась, то, пожалуйста, помогите автору с лечением. Подробности тут.

5 / 5 / 2

Регистрация: 04.10.2010

Сообщений: 205

1

24.06.2015, 22:14. Показов 13406. Ответов 3


Студворк — интернет-сервис помощи студентам

Всем привет!
Не получается реализовать Cut и Copy (можно и для Range). Хочу на первом листе Excel выделить диапазон ячеек [A1:A10] и вставить его в [B3:B12], к примеру В сети смотрю примеры, но нужный не попадается.



0



Mawrat

13094 / 5875 / 1706

Регистрация: 19.09.2009

Сообщений: 8,808

25.06.2015, 11:44

2

Лучший ответ Сообщение было отмечено Пётр Нефедов как решение

Решение

Пример. Копирование диапазона «B3:C6» в диапазон «F5:G8».

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
uses
  ComObj;
 
procedure TForm1.Button1Click(Sender: TObject);
var
  exApp, exBook, exSh, exRng : OleVariant;
  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(Handle, 'Файл с указанным именем не найден. Действие отменено.',
      'Внимание!', MB_OK + MB_ICONWARNING + MB_APPLMODAL);
    Exit;
  end;
 
  //Запуск экземпляра MS Excel и получение ссылки на интерфейс его корневого объекта 'Excel.Application'.
  exApp := CreateOleObject('Excel.Application');
  //Делаем видимым окно MS Excel.
  exApp.Visible := True;
  //Открытие рабочей книги и получение ссылки на её интерфейс.
  exBook := exApp.WorkBooks.Open(FileName:=Od.FileName);
  //Получаем ссылку на интерфейс первого рабочего листа в рабочей книге.
  exSh := exBook.WorkSheets[1];
 
  //Определяем копируемый диапазон. Пускай его адрес будет таким: 'B3:C6'.
  exRng := exSh.Range[exSh.Cells[3, 2], exSh.Cells[6, 3]]; //Или так: exRng := exSh.Range['B3:C6'];
  //Определяем место вставки - в виде верхней левой ячейки в области вставки.
  //Пускай это будет ячейка с адресом 'F5'.
  //Выполняем копирование и вставку.
  exRng.Copy(Destination:=exSh.Cells[5, 6]); //Или так: exRng.Copy(Destination:=exSh.Range['F5']);
 
  ShowMessage('Копирование выполнено.');
end;



0



Пётр Нефедов

5 / 5 / 2

Регистрация: 04.10.2010

Сообщений: 205

25.06.2015, 20:33

 [ТС]

3

Цитата
Сообщение от Mawrat
Посмотреть сообщение

Пример. Копирование диапазона «B3:C6» в диапазон «F5:G8».

Интересно, попробую)
Сделал до этого утром так:

Delphi
1
2
exApp.ActiveWorkBook.WorkSheets[1].Range['A1:A10'].Copy;
exApp.ActiveWorkBook.WorkSheets[1].Range['B5:B15'].PasteSpecial;



0



Mawrat

13094 / 5875 / 1706

Регистрация: 19.09.2009

Сообщений: 8,808

26.06.2015, 10:23

4

Лучший ответ Сообщение было отмечено Пётр Нефедов как решение

Решение

Да, можно и таким образом сделать — через специальную вставку. При этом можно вставить, например, только значениея ячеек или только их оформление и т. д.. Например, если требуется вставка только значений ячеек:

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
procedure TForm1.Button1Click(Sender: TObject);
const
  //Группа констант XlPastType.
  xlPasteValues = -4163; //Вставить только значения.
var
  exApp, exBook, exSh, exRng : OleVariant;
  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(Handle, 'Файл с указанным именем не найден. Действие отменено.',
      'Внимание!', MB_OK + MB_ICONWARNING + MB_APPLMODAL);
    Exit;
  end;
 
  //Запуск экземпляра MS Excel и получение ссылки на интерфейс его корневого объекта 'Excel.Application'.
  exApp := CreateOleObject('Excel.Application');
  //Делаем видимым окно MS Excel.
  exApp.Visible := True;
  //Открытие рабочей книги и получение ссылки на её интерфейс.
  exBook := exApp.WorkBooks.Open(FileName:=Od.FileName);
  //Получаем ссылку на интерфейс первого рабочего листа в рабочей книге.
  exSh := exBook.WorkSheets[1];
 
  //Определяем копируемый диапазон. Пускай его адрес будет таким: 'B3:C6'.
  exRng := exSh.Range[exSh.Cells[3, 2], exSh.Cells[6, 3]]; //Или так: exRng := exSh.Range['B3:C6'];
  //Определяем место вставки - в виде верхней левой ячейки в области вставки.
  //Пускай это будет ячейка с адресом 'F5'.
  //Выполняем копирование и специальную вставку - вставка только значений (Paste:=xlPasteValues).
  exRng.Copy;
  exSh.Cells[5, 6].PasteSpecial(Paste:=xlPasteValues); //Или так: exSh.Range['F5'].PastSpecial(Paste:=xlPasteValues);
  //Если копируемый участок большой, то при закрытии книги MS Excel может
  //вывести диалог с сообщением о том, что в буфере обмена имеется большой
  //блок данных, возможно - изображение.
  //Чтобы этого избежать, можно заменить данные в буфере обмена путём копирования
  //небольшого объёма данных - например, данных одной ячейки. Например, так:
  exSh.Cells[1, 1].Copy;
 
  ShowMessage('Копирование выполнено.');
end;



0



IT_Exp

Эксперт

87844 / 49110 / 22898

Регистрация: 17.06.2006

Сообщений: 92,604

26.06.2015, 10:23

Помогаю со студенческими работами здесь

Скопировать вставить диапазон
Здравствуйте.
Подскажите пожалуйста почему не работает вставка. Copy работает, выбрав уже мышью…

Как скопировать, удалить, вырезать или вставить файл?
Как скопировать, удалить, вырезать или вставить файл в VB.net

Как вставить, скопировать, вырезать текст в консольном приложении?
Я знаю, что это как бы большой скачок назад после WPF и WinForms, но всё же, понадобилось.

Как…

Как записать в массив диапазон ячеек, а затем скопировать его
Добрый день, вопрос следующего плана:

Мне нужно скопировать диапазон ячеек с Лист1 на Лист2 при…

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

Или воспользуйтесь поиском по форуму:

4

 
BoxTer
 
(2004-08-03 13:41)
[0]

Вот возникла интересная ситуевина — требуется выполнить сабж: есть в экселе табличка, например — 3 столбца, 5 строчек. Скопировав ее Ctrl+C в буфер необходимо вставить эти данные в приложении в сетку DBGrid1 с таким же количеством строк и столбцов…

Заранее благодарен.


 
Sancho ©
 
(2004-08-03 13:50)
[1]

Вообще ячейки (в буфере обмена) будут разделяться символом #9, а строки #13#10 (но это не точно т.к. копался я в этом давным-давно). Но это абсолютно не правильно, косяков не оберешься, то строчка выпадет, то ячейки объединятся особенно если ячеек много. Надо использовать OLE.


 
Digitman ©
 
(2004-08-03 13:53)
[2]


> в сетку DBGrid1 с таким же количеством строк и столбцов

если DBGrid1 связан с НД, не допускающим редактирование данных/метаданных, то затея эта крива изначально


 
KSergey ©
 
(2004-08-03 14:08)
[3]

> [2] Digitman ©   (03.08.04 13:53)

Я не пойму при чем тут все это говорить? В любом случае нет такой функциональности в стандартных компонентах. (или я ошибаюсь?)
Есть такая фигня. но это целая надстройка над DBGridEh.

Хотя сейчас глянул  наверное можно его отдельно выдрать при желании… Но жаба давит :)


 
KSergey ©
 
(2004-08-03 14:11)
[4]

Все сделано как реакция на WM_PASTE грида. Откуда оно возьмется — решать вам. Или к другому месту это все прикрутить.

Ну за одно может у кого будет конструктивная (да хоть и не очень) критика. Часть внутренних ф-ций использовалась для тестов, но проверять мне лень.

В один пост наверняка не влезет, разобью.

{******************************************************************************
* Вставка строк из клипборда
* Вставляет начиная с текущего столбца
* Вставляет при след. условиях:
*  -грид в режиме вставки
*  -GataSet и Grid допускают редактирование
******************************************************************************}

procedure TdoDBGrid.WMPaste(var Msg: TMessage);
var
 i: Integer;
 StrLst: TStringList;
 SavCursor: TCursor;

 // из модуля ClipView RXLib
 // использовалась для тестов
 function ClipboardFormatName(Format: Word): string;
 var
   Buffer: array[0..255] of Char;
 begin
   SetString(Result, Buffer, GetClipboardFormatName(Format, Buffer, 255));
   if Result = "" then
     case Format of
       CF_BITMAP: Result := "CF_BITMAP";
       CF_DIB: Result := "CF_DIB";
       CF_DIF: Result := "CF_DIF";
       CF_METAFILEPICT: Result := "CF_METAFILEPICT";
       CF_ENHMETAFILE: Result := "CF_ENHMETAFILE";
       CF_OEMTEXT: Result := "CF_OEMTEXT";
       CF_PALETTE: Result := "CF_PALETTE";
       CF_PENDATA: Result := "CF_PENDATA";
       CF_RIFF: Result := "CF_RIFF";
       CF_SYLK: Result := "CF_SYLK";
       CF_TEXT: Result := "CF_TEXT";
       CF_TIFF: Result := "CF_TIFF";
       CF_WAVE: Result := "CF_WAVE";
       CF_UNICODETEXT: Result := "CF_UNICODETEXT";
       CF_HDROP: Result := "CF_HDROP";
       CF_LOCALE: Result := "CF_LOCALE";
       CF_MAX: Result := "CF_MAX";
       CF_OWNERDISPLAY: Result := "CF_OWNERDISPLAY";
       CF_DSPTEXT: Result := "CF_OWNERDISPLAY";
       CF_DSPBITMAP: Result := "CF_OWNERDISPLAY";
       CF_DSPMETAFILEPICT: Result := "CF_OWNERDISPLAY";
       CF_DSPENHMETAFILE: Result := "CF_OWNERDISPLAY";
       CF_PRIVATEFIRST: Result := "CF_OWNERDISPLAY";
       CF_PRIVATELAST: Result := "CF_OWNERDISPLAY";
       CF_GDIOBJFIRST: Result := "CF_OWNERDISPLAY";
       CF_GDIOBJLAST: Result := "CF_OWNERDISPLAY";
     end;
 end;

 // просто список форматов данных в буфере обмена
 // использовалась для тестов
 function TextClipboardFornats: String;
 const
   YN: array [Boolean] of String = ("No", "Yes");
 var
   FormatNum, i: Integer;
 begin
   Result := "";
   for i := 0 to Clipboard.FormatCount-1 do
   begin
     FormatNum := Clipboard.Formats[i];
     Result := Result
       + IntToStr (FormatNum)
       + " (" + ClipboardFormatName(FormatNum) + ") - "
       + YN[Clipboard.HasFormat(FormatNum)] + {#13} " | ";
   end;
 end;


 
KSergey ©
 
(2004-08-03 14:12)
[5]

 // проверка строки на пустоту
 function IsEmptyStr (const AStr: String): Boolean;
 begin
   Result := Length(AStr) < 1;
 end;

 // присваивает указанное значение полю указанного столбца
 // работа через строковые значения, т.к. из клипборда вынимается текстовая информация
 procedure PasteCol (const nCol: Integer; const AStr: String);
 begin
   if NOT IsEmptyStr(AStr) then
     Columns[nCol].Field.AsString := AStr;
 end;

 // собственно добавление строки в грид
 // AStr - строка для вставки, содержащая колонки, разделенные табуляцией
 procedure PasteRow (AStr: String);
 var
   nPT: Integer;  // позиция табуляции
   nCol: Integer; // колонка для вставки
   isAllow: Boolean;  // флажек для пользователя "разрешить вставку"
 begin
   if DataLink.DataSet.State <> dsInsert then  DataLink.DataSet.Append;  // для последующих строк за первой
   try
     // предоставить пользователю возможность прописать значения в какие-либо поля при вставке строки
     isAllow := TRUE;
     if Assigned(OnRowPaste) then  OnRowPaste(Self, isAllow);
     if isAllow then
     begin
       // теперь разбить на составляющие и вставить поколоночно
       nCol := Col;
       if dgIndicator in Options then  Dec(nCol);
       while NOT IsEmptyStr(AStr) do
       begin
         nPT := Pos (#9, AStr);
         if nPT < 1 then  nPT := Length(AStr)+1;
         PasteCol (nCol, Copy(AStr, 1, nPT-1));
         Inc(nCol);
         if nCol >= Columns.Count then  Break;  // в буфере обмена было больше полей, чем осталось в гриде от текущего столбца - выход
         AStr := Copy (AStr, nPT+1, Length(AStr)-nPT);  // выделить остаток строки
       end;
       DataLink.DataSet.Post;
     end
     else
       DataLink.DataSet.Cancel;  // пользователь не разрешил вставку
   except
     DataLink.DataSet.Cancel;  // при ошибках - обязательно отменить изменения
     raise;
   end;
 end;


 
GanibalLector ©
 
(2004-08-03 14:12)
[6]

на realcoding.net поищи.Там такой вопрос подымался и весьма успешно разрешился!!!


 
KSergey ©
 
(2004-08-03 14:13)
[7]

begin   // TdoDBGrid.WMPaste
{ TODO -cГрид: попробовать сделать так, чтобы при режиме "не редактирование" вставлялось значение текста из буфера в ячейку (с предварительным переводом в состояние редактирования); возможно, придется проверить формат данных, хотя, наверняка, если не вставка (т.е. не режим для вставки строк) - пихать все в текущую ячейку }
 if ReadOnly OR NOT Assigned(DataLink.DataSet) OR NOT DataLink.DataSet.Active OR NOT DataLink.DataSet.CanModify OR (DataLink.DataSet.State <> dsInsert) OR NOT (dgdAllowRowPaste in FOptionsDO) then
   Exit;  // если по каким-то условиям нельзя произвести вставку - немедленный выход
 // итак, DataSet есть, открыт и в режиме вставки (на новой строке), ставка в грид строк - разрешена
 StrLst := TStringList.Create;
 try
   StrLst.Text := Clipboard.AsText;
   if StrLst.Count > 0 then  // буфер не пуст
   begin
     SavCursor := Screen.Cursor;
     Screen.Cursor := crHourGlass;
     DataLink.DataSet.DisableControls;
     try
       for i := 0 to StrLst.Count-1 do
         if NOT IsEmptyStr(StrLst[i]) then  PasteRow (StrLst[i]);
     finally
       DataLink.DataSet.EnableControls;
       Screen.Cursor := SavCursor;
     end;
   end;
 finally
   StrLst.Free;
 end;
end;


 
KSergey ©
 
(2004-08-03 14:15)
[8]

Работает код из [4][5][7] KSergey © так: надо перейти на новую строку в гриде (режим вставки), встать на столбец, начиная с которого будем вставлять — ну и вызвать эту ф-цию.
Возможно, условия для кого-то не приемлемы, ну подшаманить.


 
KSergey ©
 
(2004-08-03 14:17)
[9]

Да, там еще обработчик сделан OnRowPaste
Ну это можно смело убрать.


 
BoxTer
 
(2004-08-04 07:45)
[10]

2KSergey.
Бааальшое сенкс. Все заработало, придется маненько доделать для моей задачи — а так усе отлично!


 
KSergey ©
 
(2004-08-04 08:14)
[11]

> GanibalLector ©   (03.08.04 14:12)
> на realcoding.net поищи.

Там поиска нет, или я не нашел?


 
Digitman ©
 
(2004-08-04 09:25)
[12]


> KSergey ©   (03.08.04 14:08) [3]
> > [2] Digitman ©   (03.08.04 13:53)
>
> Я не пойму при чем тут все это говорить? В любом случае
> нет такой функциональности в стандартных компонентах. (или
> я ошибаюсь?)

я не о том, что функциональности такой нет, это само собой разумеется

я о том, что НД, отображаемый гридом, может иметь меньшее число полей, чем число копируемых полей

что толку вставлять в грид что-то там, если вставляемые значения должны фактически быть зафиксированы в НД ? как фиксировать «лишние» вставляемые поля ? это вызывает много вопросов …


 
GanibalLector ©
 
(2004-08-04 09:37)
[13]

2 KSergey
Ну дык в форуме…тема:Delphi


 
KSergey ©
 
(2004-08-04 10:13)
[14]

> [12] Digitman ©   (04.08.04 09:25)
> что толку вставлять в грид что-то там, если вставляемые
> значения должны фактически быть зафиксированы в НД ? как
> фиксировать «лишние» вставляемые поля ? это вызывает много
> вопросов …

Призаться, вижу 2 пути решения проблемы, без замудривания (речь идет о случае, когда каждая колонка грида соотв. полю DataSet, да еще и редактируемому; для простоты):

1.Послать пользователя «не совпадает вормат вставляемых и …»
2.Что не уместилось — ну и фиг с ним. Пользователь сам должен понимать, что если некуда вставлять — то логично, что вставляться не будет; по-моему, это выглядит вполне естественно.

Впрочем, это уже все так, слова. Обсуджать тут нечего, надо смотреть на конкретную задачу.

Впрочем, ваше замечание натолкнуло меня на то, что есть в моем коде недоработка: если столбец не видим, то по идее в него и вставлять не надо, это нелогично для пользователя, он по идее ожидает вставку только в то, что видит… Доработать надо, однако.


 
KSergey ©
 
(2004-08-04 10:15)
[15]

Да, вот еще кусочек, если интересно
Он у меня в другом месте оказался

 // проверка: содержится ли в буфере обмена формат, похожий на формат таблицы
 function TestClipBoardTable: Boolean;
 var
   s: String;
   nCF_XLTable: Integer;
   nPos, nLen: Integer;
 begin
   nCF_XLTable := RegisterClipboardFormat (PChar("XLTable"));
   Result := Clipboard.HasFormat(nCF_XLTable);  // если есть такой формат в буфере - там точно таблица
   if NOT Result AND Clipboard.HasFormat(CF_TEXT) then
   begin
     s := Clipboard.AsText;
     Result := Pos(#9, s) > 0;  // если присутствует табуляция - однозначно считаем, что в буфере - таблицы (табуляция - разделитель столбцов)
     if NOT Result then
     begin
       nPos := Pos(#13, s); // если присутствует #13
       Result := nPos > 0;  // и это не последний символ - подозрение на таблицу
       if Result then       // уточним:
       begin
         nLen := Length(s);
         if nPos = nLen-1 then       // если это предпоследний символ -
           Result := s[nLen] > " ";  // то следующий за ним должен быть буквой (а не #10, что вероятно)
       end;
     end;
   end
   else
     Result := FALSE;
 end;


Цитата:

Опиши какими символьными типами ты пользуешься для хранения-передачи данных, и кусок кода покажи, где у тебя не получается выцепить данные правильно. ИМХО тут в типе STRING заморочка.

в буфер я копирую текст так:

Код:

Clipboard.SetTextBuf(PChar(  eBuilding.Text+#9+#9+AnsiUpperCase(cbStreetsList.Text)+#9+#9+AnsiUpperCase(cbCitiesList.Text)+#9+#9+eIndex.Text+#10#13))

соответвственно, все типы — String.
по два #9 — это так и надо, ибо надо вставлять данные в поля через 2

для проверки того, как передаются поля из Excel’a в буфер и из моей проги, использовал следующий код:

Код:

procedure TZipForm.Button2Click(Sender: TObject);
var
  MyHandle: THandle;
  TextPtr: PChar;
  MyString,S: string;
  i:Integer;
begin
  ClipBoard.Open;
try
  MyHandle := Clipboard.GetAsHandle(CF_TEXT);
  TextPtr := GlobalLock(MyHandle);
  MyString := StrPas(TextPtr);
  GlobalUnlock(MyHandle);
finally
  Clipboard.Close;
end;

 if Clipboard.HasFormat(CF_TEXT) then
  S:='';
  lFullStreet.Caption:=MyString ;
  for i:=1 to length(MyString)
  do S:=S+IntToStr(Ord(MyString[i]))+' ';
 lFullStreet.Caption:=S;

end;

анализирует содержимое буфера по нажатию клавиши, в результате в строку S передается через пробел ASCII коды того, что есть в буфере (может проблема в том, что текст в буфере НЕ надо принимать за текст?). анализ этого показывает, что моя программа и Excel передают данные в одинаковом формате… но вот другая прога (куда их вставляют) понимает их по-разному…

Цитата:

ЧересЧеловек:
‘text1’+’#9’+’text2’+’#10#13’

тогда просто в буфере будет строка ‘text1#9text2#10#13’

Цитата:

ЧересЧеловек:
и вставлял в офис2003

мне нужно не в офис вставлять, а в другую прогу! (офис сам пробелы или Tab заменяет на некий разделитель ячеек), мне нужно сделать такое содержимое буфера, как будто эти данные были переданы из офиса!

>
Paste to ExcelApplication

  • Подписаться на тему
  • Сообщить другу
  • Скачать/распечатать тему



Сообщ.
#1

,
30.08.06, 11:48

    Вопрос на засыпку (от слова спать) :)
    Как вставить из буфера обмена таблицу в Excel, используя ExcelApplication ?

    Нигде в нете не могу найти ответ!
    Впрочем, нашёл где-то такую строчку:
    OLEVariant(Workbooks[1].Worksheets[1] ).PasteSpecial;

    Это работает, но если запущено больше одного экселя, то вставляет ОНО текст не в ту книгу, которую надо! И вообще, что это за зверь — OLEVariant? Я его боюсь :o
    Можно без него обойтись?


    dron-s



    Сообщ.
    #2

    ,
    30.08.06, 11:53

      Цитата ILUXER @ 30.08.06, 11:48

      И вообще, что это за зверь — OLEVariant

      можно просто Variant и CreateOleObject
      сделай подобную операцию в Excel’е и запиши макрос, потом посмотри код… перевести на Delphi не составит большого труда


      Albinos_X



      Сообщ.
      #3

      ,
      30.08.06, 12:45

        Full Member

        ***

        Рейтинг (т): 16


        ILUXER



        Сообщ.
        #4

        ,
        30.08.06, 14:20

          dron-s
          Пробовал, там написано ActiveSheet.Paste
          Это никак не помогает.
          В Delphi я не могу написать Workbooks[1].ActiveSheet.Paste потому что Undeclared identifer Paste.

          Albinos_X
          Был уже тут, читал. Но… ничего про вставку в Excel из clipboarda, всё только про Word.

          Guru

          volvo877



          Сообщ.
          #5

          ,
          30.08.06, 15:38

            Цитата ILUXER @ 30.08.06, 14:20

            В Delphi я не могу написать Workbooks[1].ActiveSheet.Paste потому что Undeclared identifer Paste.

            А вот с этого места — поподробнее… У меня все компилируется… Покажи, как запускаешь Excel.


            Albinos_X



            Сообщ.
            #6

            ,
            30.08.06, 15:49

              Full Member

              ***

              Рейтинг (т): 16

              там про Excel тоже есть, просто не внимательно прочитал статью… поясню… дело в том, что если ты запустишь сначала книгу отдельно, потом свою книгу, но обращаться будешь по :

              ExpandedWrap disabled

                OLEVariant(Workbooks[1].Worksheets[1] ).PasteSpecial;

              то она уже никак не будет иметь индекс = 1, твоя книга будет уже второй т.д. и т.п., то же самое если запустишь несколько книг, потом свою, потом часть закроешь, то индек изменится…
              поэтому следует :
              1. При открытии сразу связывать объект (переменную) с этой книгой или конкретным листом и через него обращаться

              2. Производить поиск нужной книги и листа по заголовку в массиве книг

              3. Фиксировать при запуске индекс книги и следить за её перемещением в массиве

              считаю самым оптимальным первый вариант…

              а через имеющиеся компаненты это уже не сложно сделать
              например для ExcelApplication:

              ExpandedWrap disabled

                ExcelApplication1.Range[‘A1’,EmptyParam]._PasteSpecial(EmptyParam,EmptyParam,EmptyParam,EmptyParam);

              для ExcelWorksheet1 :
              к примеру

              ExpandedWrap disabled

                ExcelWorksheet1._PasteSpecial;

              или

              ExpandedWrap disabled

                ExcelWorksheet1.Paste;

              Сообщение отредактировано: Albinos_X — 30.08.06, 16:07


              ILUXER



              Сообщ.
              #7

              ,
              30.08.06, 16:47

                2 Albinos_X

                ExpandedWrap disabled

                  ExcelApplication1.Range[‘A1’,EmptyParam]._PasteSpecial(EmptyParam,EmptyParam,EmptyParam,EmptyParam);

                компилируется, если убрать знак подчёркивания перед _PasteSpecial. Что этот знак обозначает, не догадываюсь, но вставки всё равно не происходит, даже если заменить A1 на EmptyParam. Ошибку выдаёт дебагер во время выполнения «Could not convert type (Error) to type(Boolean)» — точно не помню, что-то вроде этого

                Далее

                ExpandedWrap disabled

                  ExcelWorksheet1.Paste;

                Но у Workшитов нету такой функции! Когда я пишу Workbooks[1].Worksheets[1].paste , Delphi не понимает!

                2 volvo877 & 2 ALL
                На форме TExcelApplication
                AutoConnect=FALSE
                AutoQuit=TRUE

                В программе:

                ExpandedWrap disabled

                  with ExcelApplication1 do

                  begin

                    Connect;

                    Workbooks.Add(EmptyParam, 0);

                    Clipboard.Clear;

                    //…

                    // Здесь в буфер обмена накапливаются нужные данные

                    // …

                    OLEVariant(Workbooks[1].Worksheets[1] ).PasteSpecial; //Вот эту строчку нужно заменить

                  //чтобы текст вставлялся в нужную книгу

                    //…

                    // Здесь форматирование ячеек и всё такое

                    //…

                    Visible[0]:=true;  //сделать Excel видимым

                    if WindowState[0] = xlMinimized then WindowState[0] := xlNormal;

                    ScreenUpdating[0] := true;

                    Clipboard.Clear;

                  end;


                Albinos_X



                Сообщ.
                #8

                ,
                30.08.06, 17:07

                  Full Member

                  ***

                  Рейтинг (т): 16

                  Цитата ILUXER @ 30.08.06, 16:47

                  омпилируется, если убрать знак подчёркивания перед _PasteSpecial

                  у тебя какая версия Delphi и Office ?
                  У меня именно они и есть…

                  Цитата ILUXER @ 30.08.06, 16:47

                  Но у Workшитов нету такой функции! Когда я пишу Workbooks[1].Worksheets[1].paste

                  есть… но тот который ты используешь неверен (!!!)….

                  ExpandedWrap disabled

                      ExcelApplication1.ConnectKind:=ckNewInstance;

                      ExcelApplication1.AutoConnect:=true;

                      ExcelApplication1.SheetsInNewWorkbook[LOCALE_USER_DEFAULT]:=1;

                      ExcelApplication1.Workbooks.Add(EmptyParam,LOCALE_USER_DEFAULT);

                      ExcelWorksheet1.ConnectTo(ExcelApplication1.ActiveWorkbook.ActiveSheet as ExcelWorkSheet);

                      //…

                      // Здесь в буфер обмена накапливаются нужные данные

                      // …

                      ExcelWorksheet1._PasteSpecial;

                      //чтобы текст вставлялся в нужную книгу

                      //…

                      // Здесь форматирование ячеек и всё такое

                      //…  

                      ExcelApplication1.Visible[LOCALE_USER_DEFAULT]:=true;  //сделать Excel видимым

                      if WindowState[0] = xlMinimized then WindowState[0] := xlNormal;

                      ScreenUpdating[0] := true;

                      Clipboard.Clear;

                  в наборе имеется восемь методов ExcelWorksheet1._PasteSpecial
                  с нулём и до 7 параметров:
                  ExcelWorksheet1._PasteSpecial(Format, Link, DisplayAsIcon, IconFileName, IconIdex, IconLabel, lcid);

                  все OleVariant кроме последнего, он Integer…

                  Добавлено 30.08.06, 17:12

                  Цитата Albinos_X @ 30.08.06, 17:07

                  но тот который ты используешь неверен (!!!)…

                  с помощью него получишь только ссылку на объект…
                  и к тому же это не решит твою проблему с «промахом» страницей…

                  Добавлено 30.08.06, 17:13
                  да и ещё… кинь на форму ТExcelWorksheet…

                  Добавлено 30.08.06, 17:15

                  Цитата Albinos_X @ 30.08.06, 17:07

                  есть… но тот который ты используешь неверен (!!!)….

                  ты попутал доступ через компоненту и через OleVariant…


                  ILUXER



                  Сообщ.
                  #9

                  ,
                  30.08.06, 18:09

                    Всё заработало, огромное спасибо!
                    Версия Delphi 7, Office 2002.
                    Комоненты на поллитре компонентов (вкладка Servers) — все с добавкой 2000! А будет ли программа работать с другой версией Офиса? :o


                    Albinos_X



                    Сообщ.
                    #10

                    ,
                    31.08.06, 01:16

                      Full Member

                      ***

                      Рейтинг (т): 16

                      должна… если бы было _PasteSpecial с параметрами, то может чем-то ХР от 2000 и отличалось бы, так проблем не должно возникать…

                      Удачи!


                      ILUXER



                      Сообщ.
                      #11

                      ,
                      31.08.06, 16:03

                        С чем связано то, что данные иногда вставляются в непонятной кодировке?


                        Albinos_X



                        Сообщ.
                        #12

                        ,
                        31.08.06, 16:35

                          Full Member

                          ***

                          Рейтинг (т): 16

                          вероятно с тем, откуда копируешь… тоже самое, как русский текст копируется в окно ответа здесь…

                          0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)

                          0 пользователей:

                          • Предыдущая тема
                          • Delphi: Общие вопросы
                          • Следующая тема

                          [ Script execution time: 0,0375 ]   [ 16 queries used ]   [ Generated: 13.04.23, 22:37 GMT ]  

                          Понравилась статья? Поделить с друзьями:
                        • Delphi excel sheets sheet
                        • Delphi excel select all
                        • Delphi excel range all
                        • Delphi excel ole error
                        • Deliver on your word