Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2015.01.11;
Скачать: CL | DM;

Вниз

Текст по столбцам в Excel из Delphi XE4   Найти похожие ветки 

 
_guest_   (2013-12-17 13:51) [0]

Не могу разобрать текст по столбцам в Excel XP из Delphi XE4. А вообще задача конвертировать из csv в xls (если может кто подскажет другие способы кроме построчного). В бейсике макрос такой:
Columns("A:A").Select
   Selection.TextToColumns Destination:=Range("A1"), DataType:=xlDelimited, _
       TextQualifier:=xlDoubleQuote, ConsecutiveDelimiter:=False, Tab:=True, _
       Semicolon:=False, Comma:=False, Space:=False, Other:=False, FieldInfo _
       :=Array(Array(1, 1), Array(2, 1), Array(3, 1), Array(4, 1), Array(5, 1), Array(6, 1), _
       Array(7, 1), Array(8, 1), Array(9, 1), Array(10, 1), Array(11, 1), Array(12, 1), Array(13, 1 _
       ), Array(14, 1), Array(15, 1), Array(16, 1), Array(17, 1), Array(18, 1), Array(19, 1), Array _
       (20, 1), Array(21, 1), Array(22, 1), Array(23, 1), Array(24, 1), Array(25, 1), Array(26, 1), _
       Array(27, 1), Array(28, 1), Array(29, 1), Array(30, 1), Array(31, 1), Array(32, 1), Array( _
       33, 1), Array(34, 1), Array(35, 1), Array(36, 1), Array(37, 1), Array(38, 1), Array(39, 1), _
       Array(40, 1), Array(41, 1), Array(42, 1), Array(43, 1), Array(44, 1), Array(45, 1), Array( _
       46, 1), Array(47, 1), Array(48, 1), Array(49, 1), Array(50, 1), Array(51, 1), Array(52, 1), _
       Array(53, 1), Array(54, 1), Array(55, 1), Array(56, 1), Array(57, 1), Array(58, 1), Array( _
       59, 1), Array(60, 1), Array(61, 1), Array(62, 1), Array(63, 1), Array(64, 1), Array(65, 1), _
       Array(66, 1), Array(67, 1), Array(68, 1), Array(69, 1), Array(70, 1), Array(71, 1), Array( _
       72, 1)), TrailingMinusNu


Пробую так, открывая файл csv, а сохраняя в xls:

....
   ExcelApp: TExcelApplication;
   ExcelWB: TExcelWorkbook;
   ExcelWS: TExcelWorksheet;
   FieldInfo: OleVariant;
....
 try
     ExcelApp.ConnectKind := ckRunningOrNew;
     ExcelApp.Connect;
     ExcelApp.Workbooks.Add(CSVFileName, LOCALE_USER_DEFAULT);

     ExcelWB.ConnectTo(ExcelApp.ActiveWorkbook);
     ExcelWS.ConnectTo(ExcelWB.Worksheets[1] as _Worksheet);

     ColMax := 72;  //столбцов
     FieldInfo := VarArrayCreate([0, ColMax], varVariant);  

     for I := 0 to ColMax do
       FieldInfo[i] := VarArrayOf([i, 1]);

ExcelWS.Range["A1", "A100000"].TextToColumns(ExcelWS.Range["A1", "A1"],  xlDelimited, xlDoubleQuote, False, True, False, False, False, False, "", FieldInfo, ".", "", True);

ExcelApp.ActiveWorkbook.SaveAs(XLSFileName, EmptyParam{FileFormat}, EmptyParam,
        EmptyParam, EmptyParam, EmptyParam, xlNoChanges, EmptyParam,
        EmptyParam, EmptyParam, EmptyParam, 0, LOCALE_USER_DEFAULT);

   finally
     ExcelWS.Disconnect;
     ExcelWB.Close(1);
     ExcelApp.UserControl := True;
     ExcelApp.Quit;
   end;


Отрабатывает, но изменений нет.
Не могу найти примеров под Excel XP, все только под старые, а похоже много чего изменилось, например, не могу найти Selection  чтобы Selection.TextToColumns и так далее.  Подскажите, пожалуйста, в чем ошибка в моем коде.


 
Ega23 ©   (2013-12-17 14:18) [1]

Подготавливаешь вариантный массив из своих значений. Потом одним чохом вставляешь:

WS.Range[WS.Cells.Item[FData.StartRowNr, 1],
             WS.Cells.Item[FData.StartRowNr + FData.TotalRowsCount - 1, 18]].Value := FData.DataArray;


 
sniknik ©   (2013-12-17 14:21) [2]

> Не могу найти примеров под Excel XP
универсальный пример, стартуешь макрос, делаешь "руками". смотришь что получилось, пример -  
Sub Ìàêðîñ1()
"
" Ìàêðîñ1 Ìàêðîñ
" Ìàêðîñ çàïèñàí 17.12.2013 (ws-131)
"

"
   ChDir "D:\"
   Workbooks.Open Filename:="D:\test.csv"
   ActiveWorkbook.SaveAs Filename:="D:\test.xls", FileFormat:=xlNormal, _
       Password:="", WriteResPassword:="", ReadOnlyRecommended:=False, _
       CreateBackup:=False
End Sub


 
_guest_   (2013-12-17 15:10) [3]


> Ega23 ©   (17.12.13 14:18) [1]

Речь идет о десятках мегабайт, хотелось бы обойтись средствами самого Excel"а раз уж он это умеет.
> sniknik ©   (17.12.13 14:21) [2]
> универсальный пример, стартуешь макрос, делаешь "руками".
>  смотришь что получилось

Макрос, сделанный "руками", я привел в самом начале, попробовал адаптировать, но не очень удачно. Не нашел: Selection, Columns и не очень разобрался с FieldInfo. В Делфи7 и Excel97 прекрасно отрабатывала связка ExcelWS.Columns[1].Select;
ExcelWS.Selection.TextToColumns;

сейчас не работает, я изменил код - результата не получил, если кто видит ошибку, подскажите.


 
_guest_   (2013-12-17 15:13) [4]

Т.е. файл то сохраняется, но без разбивки на столбцы, ошибок при работе не выдает :(


 
sniknik ©   (2013-12-17 15:18) [5]

> Не нашел: Selection
http://delphimaster.net/view/15-1386856880/

но вообще, нафиг не нужен, см. пример "моего" макроса.


 
_guest_   (2013-12-17 15:43) [6]


> sniknik ©   (17.12.13 15:18) [5]

Я далек от мысли, что Вы предлагаете мне поменять расширение файла, так как у меня после отработки Вашего макроса, по большому счету, только это и происходит, из чего заключаю, что преобразование у Вас происходит на этапе открытия файла. Какие настройки у пользователя будут стоять, я не знаю. У меня вот автоматом не преобразовывает, хотя расширение csv/tsv файла должно бы однозначно говорить о его содержимом. Вопрос пока для меня остается открытым.


 
_guest_   (2013-12-17 15:51) [7]

Поправочка: с расширением tsv (а в качестве разделителя используется таб) содержимое преобразуется автоматически. Надо полагать, что если разделителем поставить запятую, то и csv откроется правильно. С практической точки зрения, задача решена. Но все-таки на будущее хотелось бы довести и преобразование вручную до ума - может пригодиться, так что пока еще сам поэкспериментирую и подожду, вдруг кто поможет.


 
_guest_   (2013-12-17 15:59) [8]

Кроме того разделителем может оказаться и какой-либо другой символ. Так что на расширение файла полагаться наверно не стоит. По хорошему то надо бы пойти посмотреть biff, но что-то мне подсказывает, что это надолго, а со временем - не очень.


 
_guest_   (2013-12-17 17:10) [9]

Если кому интересен работающий вариант, то вот он:
ExcelWS.Range["A1", "A1"].EntireColumn.TextToColumns(ExcelWS.Range["A1", "A1"],
       xlDelimited, xlDoubleQuote, False, True, False, False, False, False, EmptyParam,
       null, ".", EmptyParam, True);


Чем EmptyParam лучше чем ""(пустая строка) в качестве ThousandsSeparator я не понимаю, но очевидно лучше :) я с вариантами почти не сталкиваюсь. С null тоже работает.


 
sniknik ©   (2013-12-17 18:30) [10]

> хотя расширение csv/tsv файла должно бы однозначно говорить о его содержимом.
csv не однозначный формат, с другой стороны то в каком виде читать настраивается, для примера полная (не уверен, тоже из макроса, что поставило то поставило) форма открытия
   Workbooks.OpenText Filename:="D:\test.csv", Origin:=1251, StartRow:=1, _
       DataType:=xlDelimited, TextQualifier:=xlDoubleQuote, ConsecutiveDelimiter _
       :=False, Tab:=False, Semicolon:=False, Comma:=True, Space:=False, _
       Other:=False, FieldInfo:=Array(Array(1, 1), Array(2, 1), Array(3, 1), Array(4, 1)) _
       , TrailingMinusNumbers:=True


по умолчанию не запятая, а точка с запятой


 
_guest_   (2013-12-18 08:51) [11]


> sniknik ©   (17.12.13 18:30) [10]
по умолчанию не запятая, а точка с запятой

Не знаю, что там стоит по-умолчанию, а только csv - это Comma Separated Values, т.е.  "значения, разделённые запятой", tsv - соответственно табом. Если точкой с запятой, то по аналогии расширение должно бы быть ssv, извиняюсь за лирическое отступление. А за макрос большое спасибо,  может пригодиться. Очень похоже на то, что получилось у меня. Может даже и в нем вместо FieldInfo можно подсунуть null для упрощения, если количество столбцов не известно заранее.


 
Inovet ©   (2013-12-18 09:05) [12]

> [11] _guest_   (18.12.13 08:51)
> Comma Separated Values, т.е.  «значения, разделённые запятой»,
> tsv — соответственно табом. Если точкой с запятой, то по
> аналогии расширение должно бы быть ssv

И так для всех символов.


 
_guest_   (2013-12-18 09:11) [13]


> Inovet ©   (18.12.13 09:05) [12]
И так для всех символов.

Для csv существует спецификация, даже ссылок приводить не буду, информации полно.


 
sniknik ©   (2013-12-18 10:17) [14]

> Не знаю, что там стоит по-умолчанию, а только csv
проверь, сделай такой, и выполнить на нем код sniknik ©   (17.12.13 14:21) [2]

> Для csv существует спецификация
а ты думаешь откуда я свои знания почерпнул? именно в спецификации (справке excel) и написано -
Format - Должен иметь одно из следующих значений: «TabDelimited», «CSVDelimited», «Delimited» (<одиночный символ разделителя>) или «FixedLength». Разделителем для формата «Delimited» может служить любой одиночный символ кроме символа прямых кавычек (").

+
http://ru.wikipedia.org/wiki/CSV
Несмотря на наличие RFC, на сегодняшний день под CSV, как правило, понимают набор значений, разделенных какими угодно разделителями, в какой угодно кодировке с какими угодно окончаниями строк. Это значительно затрудняет перенос данных из одних программ в другие, несмотря на всю простоту реализации поддержки CSV.
и начался бардак именно с мелкософта, ИМХО.


 
sniknik ©   (2013-12-18 10:36) [15]

+
> кроме символа прямых кавычек (").
и его можно, просто до этого сменить TextDelimiter.


 
_guest_   (2013-12-18 11:12) [16]


> sniknik ©   (18.12.13 10:17) [14]
> sniknik ©   (18.12.13 10:36) [15]

Да я все это прекрасно понимаю. И код Ваш рабочий и спасибо еще раз за него. Я и хотел подчеркнуть возможные нюансы в работе с csv, что просто открытие файла в txcel"е не гарантирует его преобразования, это зависит от используемого разделителя. Меня как раз позабавило, что я переименовал расширение в tsv и тут же все заработало. Т.е. MS следует формальной логике, отталкиваясь от расширения.



Страницы: 1 вся ветка

Текущий архив: 2015.01.11;
Скачать: CL | DM;

Наверх




Память: 0.52 MB
Время: 0.004 c
15-1402173002
Юрий
2014-06-08 00:30
2015.01.11
С днем рождения ! 8 июня 2014 воскресенье


11-1256888147
Инна
2009-10-30 10:35
2015.01.11
Canvas


15-1402259403
Юрий
2014-06-09 00:30
2015.01.11
С днем рождения ! 9 июня 2014 понедельник


15-1402126202
Юрий
2014-06-07 11:30
2015.01.11
С днем рождения ! 7 июня 2014 суббота


2-1386666267
Scott Storch
2013-12-10 13:04
2015.01.11
Оптимизация SELECT-запроса