Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 2015.01.11;
Скачать: [xml.tar.bz2];

Вниз

Текст по столбцам в 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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.5 MB
Время: 0.002 c
11-1238844674
SPeller
2009-04-04 15:31
2015.01.11
MCK и D2009


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


2-1387118291
demi
2013-12-15 18:38
2015.01.11
фильтр в делфи


2-1387206682
demi
2013-12-16 19:11
2015.01.11
Фильтрация


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





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский