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

Вниз

Господа, помогите с чтением данных из Excel   Найти похожие ветки 

 
Санька   (2002-03-05 13:28) [0]

Проблема в следующем:
Заказчик дает файл Екселя, а я перекачиваю все данные в локальную
БД для дальнейшей обработки. Обидно, что этот файл не очень грамотно сотавлен и в ячейках (вместо автоматического переноса)
куча пробелов м/у словами и нажатых Вводов.... При копировании столбца в таблицу все эти лишние знаки выглядят некрасиво, и правится не очень то. Если поможет - вот код. Может подскажет кто.
procedure TForm1.BitBtn1Click(Sender: TObject);
var i, k: integer;
n: string;
AppExcel, Value : Variant;
begin
i:=6; // с шестой строки в книге екселя
AppExcel:=CreateOleObject("Excel.Application");
AppExcel.Workbooks.Open("c:\111.xls", False);
AppExcel.Visible := True;
while i<=34 do
begin
n:=AppExcel.Cells.item[i,4].Value;
taSS.edit;
taSS.insert;
taSs.fieldbyname("Name").AsString:=n;

taSS.post;
taSS.Next;
i:=i+1;
end;
end;

А может, подскажите, как лучше все это организовать...
Если можно, не отсылайте на сайты D-Excel был уже...
Ну, задолбал, наверное. Заранее, спасибо!!!


 
MetallAdm   (2002-03-05 16:38) [1]

А нельзя ли лишние пробелы убирать итд ??

n:=AppExcel.Cells.item[i,4].AsString; --- Сдеся тоже как стринг делаешь Если она строковая
taSS.edit;
taSS.insert;
DelSpaces(N); ---типа так :))

taSs.fieldbyname("Name").AsString:=n;


Procedure DelSpaces(Var xx:String);
Var
lt,i:Integer;
ll,l:Integer;
s:String;
b,a:Byte;
begin
s:=xx;
ll:=1;
Lt:=Length(S);
l:=0;
a:=0;
for i:=1 to lt do
begin
if String(s[i])=" " Then inc(l);
if String(s[i])="*" Then a:=1;
end;
If l=lt Then
begin
s:="*";
a:=1;
ll:=1;
end;
if a=0 Then
begin
b:=0;
For i:=lt downto 2 do
begin
if String(s[i])<>" " then
if b=0 then
begin
ll:=i;
b:=1;
end;
end;
If ll>2 Then Setlength(s,ll) else s:="*";
end;
xx:=s;
end;

Да хоть ентой процедурой
когда то, тоже писал ну незнаю насколько она правильна
давно енто было

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

думаю уберешь :)


 
Санька   (2002-03-05 17:29) [2]

Спасибочки большое - попробую. Если, что обращусь снова к тебе
(насчет зведулек :) ).
А насчет упращения задачи в принципе, ни у кого не возникает
мыслей. Мобыть кто-то сталкивался с проблемой...
Кстати, в моем случае, с этой процедуркой комп "думает" очень долго (пока все ячейки переберет, пока в строки в табле вставит)
Будет очень интересно узнать Ваше мнение, спецы.


 
MetallAdm   (2002-03-05 17:47) [3]

Да кстати ента процедура убирает
только с конца пробелы лишние

но думаю нетрудно сделать такую вещь
которая находит отдельные слова в строке
а потом их попорядку через пробел мона в одну строку запихнуть



 
Санька   (2002-03-06 09:05) [4]

Дас....
Не думаю, что у мня это быстро получится: как то с паскалем
чистым (в плане обработок строк) не приходилось много сталкиваться. Я все больше по БД. Ну лана - попробую.. Сэнкс.
А у других мыслей нет чтоли.... Ау!


 
gek   (2002-03-06 09:40) [5]

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


 
MetallAdm   (2002-03-06 09:51) [6]

Воот нечто похожее я когда то делал на Турбо пискале :))

У мя загружает текстовой файл и слава пихает в массив
то есть выбирает отдельные слова из массива
Ну если непонятен будет спрашивай я сам то

Procedure LoadFile(Var txt:POuts;Fl:String);
Var
i,j,k:Word;
s:Word;
buff:Array [1..lhtWord] of Byte;
bRead,bWrite:Word;
Sk,NumL:Word;
Strs:String;
begin
Assign(Fls,Fl);
Reset(Fls,1);
Size:=FileSize(Fls);
If Size<65000 then
begin
BlockRead(Fls,lBuff^,Size,bRead);
i:=1;
While (i<=Size)and(lBuff^[i]=" ")or(lBuff^[i]=#13)or(lBuff^[i]=#10) do
begin
Inc(i);
end;
AddW:=1;
k:=0;
For s:=i to Size do
begin
j:=0;
If (lbuff^[s]<>" ")and(lBuff^[s]<>#13)and(lBuff^[s]<>#10)and(lBuff^[s]<>".")and(lBuff^[s]<>",")Then
begin
{ Write(lbuff^[s]);}
Inc(k);
Strs[k]:=lbuff^[s];
Strs[0]:=Chr(k);
txt^[addW]:=Strs;
end
else
begin
j:=s;
k:=0;
If (lBuff^[j]=".")or(lBuff^[j]=",") Then
begin
{ Strs[k]:=lbuff^[s];
Strs[0]:=Chr(k);}
If (lBuff^[j+1]<>" ")or(lBuff^[j+1]<>#13)or(lBuff^[j+1]<>#10) Then
begin
Inc(AddW);
s:=j;
end;
end
else
begin
While (lBuff^[j]=" ")or(lBuff^[j]=#13)or(lBuff^[j]=#10) do
begin
Inc(j);
{ If (lBuff^[j]=#13)or(lBuff^[j]=#10) Then Write("|") else Write("+");}
end;
Inc(AddW);
s:=j-1;
end;
end;
end;
end;
end;


Хех Длинная процедурка :))


 
Shirson   (2002-03-06 12:50) [7]

Мда...
В XL есть две вот таких функции:
1. Clean(Text) Удаляет из текста все nonprintable символы (перевод строки к ним относится).
2. Trim(Text) Удаляет из текста все пробелы, за исключением единичных, между словами.

Итого, сделав =Trim(Clean(A1)) можно избежать Длинных Процедурок :)


 
Санька   (2002-03-06 14:10) [8]

>Shirson
Уточни, пжалуста, эти функции делать то непосредственно в екселе, или их мона вызвать из делфей?


 
Shirson   (2002-03-06 14:35) [9]

>Санька

Можно непосредственно в XL. Можно и из Делфи - завести в XL какую-нибудь ячейку, с формулой =Trim(Clean(A1)), только вместо А1 подставлять все ячейки которые нужно обработать, а с данной считывать данные в Делфи и кидать в базу... э.. только несовсем ясно, зачем тут нужен этап с Делфи :) Можно кидать данные в базу напрямую из XL :)))


 
Санька   (2002-03-06 14:45) [10]

>Shirson
Попробую, спасибочки...
Насчет прямой передачи в БД: это ведь надоть делать средствами екселя - а юзвери мои не дотумкают... Потом, если данные повторяются, то мне сложновато будет это отследить. А так - копирую в промежуточную БД, а потом средствами SQL делаю и отбираю что хочу для основной... Вообщето проект довольно таки туповатый :) Основная прога работает давно и все отлажено, но от скуки начинаю беситься и выдумывать новые упрощения для юзеров.
Ну ладна, пойду далее мучаться. Всем спасибо!!! Помогли!
Скоро наверное опять обращусь. ;)


 
Санька   (2002-03-06 15:13) [11]

>Shirson
Кстати, попробовал так:

n:=AppExcel.Cells.item[i,4].Value;
Trim(n); - это работает, пробелы удаляет
Clean(n); - а эта ф-я делфям неизвестна

Может, что нибудь заменит эту функцию. В хелпе по работе со строками порылся - ничего :( . ???????


 
TIP   (2002-03-06 15:31) [12]

А есть же для Дельфей отличная библиотека Qstrings
причем работа со строками на ассемблере.


 
Shirson   (2002-03-06 15:35) [13]

Вообще, в Делфи (по крайней мере в D6), функция trim удаляет пробелы в начале строки, в конце строки и все control characters из самой строки. (как в хелпе рылся? :) )
Попробуй только тримом строку обработать - что получается?


 
Shirson   (2002-03-06 15:40) [14]

>Санька
"Насчет прямой передачи в БД: это ведь надоть делать средствами екселя - а юзвери мои не дотумкают... Потом, если данные повторяются, то мне сложновато будет это отследить. "

Хозяин - барин :) Я бы огород не городил, а сделал все в XL. И юзверям нужно было бы нажимать одну пимпу, не задумываясь о механизме работы системы. А там и проверку, какую хочешь можно сделать и UI наворотить и пр. Но если хочется на делфи - значит нужно :)


 
Санька   (2002-03-06 16:21) [15]

:))))))) Да, я то думал, что давно из чайников вышел... :)
Работа со строками, говорите, а trim - ассемблеровская фишка, %)
короче %%(((.
Ну"с, со строками дык со строками... Только всеравно ничего не нахожу кроме стыковки, поиска символов и т.п. и т.д., а про удаление пробелов и "вводов" и "табов" и еже с ними - ничего не вижу кроме тримов.
Если подскажете горе-программеру - спасибо.
Если нет - пойду учить инглиш и куплу D for dummers :))
А, счас всем еще раз спасибо, пошел напьюсь!!!



 
dmitryK   (2002-03-06 18:13) [16]


> А насчет упращения задачи в принципе, ни у кого не возникает
> мыслей. Мобыть кто-то сталкивался с проблемой...
> Кстати, в моем случае, с этой процедуркой комп "думает"
> очень долго (пока все ячейки переберет, пока в строки в
> табле вставит)
> Будет очень интересно узнать Ваше мнение, спецы.


Ничего удивительного что так долго думает. Код-то тормазнутый.
В двух словах, как можно оптимизировать. Это исходный код:


> procedure TForm1.BitBtn1Click(Sender: TObject);
> var i, k: integer;
> n: string;
> AppExcel, Value : Variant;
> begin
> i:=6; // с шестой строки в книге екселя
> AppExcel:=CreateOleObject("Excel.Application");
> AppExcel.Workbooks.Open("c:\111.xls", False);
> AppExcel.Visible := True;
> while i<=34 do
> begin
> n:=AppExcel.Cells.item[i,4].Value;
> taSS.edit;
> taSS.insert;
> taSs.fieldbyname("Name").AsString:=n;
>
> taSS.post;
> taSS.Next;
> i:=i+1;
> end;
> end;


AppExcel.Visible := True; - это зачем?? что бы медленне работало?
данный кусок кода указывает необходимость визуализировать процесс работы с XL, что естественно тормозит работу.

n:=AppExcel.Cells.item[i,4].Value; - код из учебника, абсолютно корректный, но при этом абсолютно тормозной. Не знаю точно как это работает (на уровне ОС), но по времени абсолютно без разницы сколько сколько ты будешь данных выгружать из странички книги - одну ячейку или 1000. Для этого придется создать динамический массив необходимого размера и загрузить туда Range.
А уже потом анализировать этот массив, что само по себе намного быстрее.

А вот этот фрагмент кода мне не совсем ясен
> taSS.edit;
> taSS.insert;
> taSs.fieldbyname("Name").AsString:=n;
>
> taSS.post;
> taSS.Next;

пытаешься заменять уже имеющиеся строки?? хотя вроде речь шла о добавлении новых?? Но в любом случае зачастую быстрее получается формировать SQL запросы целиком и выполнять их. Поскольку, согласно кода, ожидается за один прием менее 30 строк, то можно за один прием отправить весь пакет изменений (30 SQL запросов на модификацию/добавление), что тоже несколько ускорит время выполнения задачи.

и последнее
i:=i+1; - такой фрагмент лучше заменять на Inc(i);

Что касается советов по оптимизации скорости доступа к данным в XL очень рекомендую заглянуть на сайт "Королевство Дельфи" и найти статьи "По волнам интграции". Все о чем я здесь коротенько упомянул, там очень подробно описано. Почитай.

Что же касается удаления лишних пробелов, то эта проблема и выеденного яйца не стоит. Я не знаю как насчет в D6, но раньше ТРИМ вырезал только начальные и концевые пробелы. Если теперь он еще плюс к этому удаляет промежуточные управляющие символы, то все вообще просто, ну если нет, то придется полчаса потратить, что бы удалить их самому.


 
dmitryK   (2002-03-06 18:16) [17]


> TIP (06.03.02 15:31)
> А есть же для Дельфей отличная библиотека Qstrings
> причем работа со строками на ассемблере.


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


 
MetallAdm   (2002-03-06 18:57) [18]

хех да помоему у тебя вопрс о оптимицации уже поднялся :)

>Shirson кстати не знал не знал :)
все еще отвыкнуть от времен доса не могу
когда любые проги приходлось делать с нуля :))



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

Форум: "Базы";
Текущий архив: 2002.04.01;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.51 MB
Время: 0.006 c
3-33
solsoft
2002-03-06 13:43
2002.04.01
Нет доступа к Access через BDE


1-225
VJar
2002-03-20 16:10
2002.04.01
Текст скрытый звездочками


1-174
Dok_3D
2002-03-19 07:28
2002.04.01
XML-файлы большого размера


4-342
kiber
2002-01-31 01:17
2002.04.01
win api


7-326
LinX
2001-12-21 01:09
2002.04.01
Виртуальный принтер





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский