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

Вниз

поиск ячеек по excel файлам   Найти похожие ветки 

 
kate158 ©   (2009-09-22 16:03) [0]

что делаю:1.ищу excel файлы в папке (их названия у меня в мемо).2.нахожу опр ячейку по всем эксель файлам(ее адрес введен на форме в эдит поле).3. копирую название файла и значение ячейкив блокнот. вопрос таков. что неверно написано в коде (поиск ячейки по всем  файлам):

procedure TForm1.Button3Click(Sender: TObject);
var
 D1, D2 : Variant;
 E, W, SB,SH : Variant;
 i:integer;
BEGIN
   E  := CreateOleObject("Excel.Application");
     E.DisplayAlerts  := False;
     for i:=0 to Memo1.Lines.Count - 1 do
     E.WorkBooks.Open(trim(Memo1.Lines[i]), ReadOnly:=True);
     W := E.WorkBooks.Item[1];
     SH := W.Sheets.Item[1];
        D1 :=  SH.Range[EditAA.Text].Value;
        i:=i+1;
           showmessage(d1);
           //E.Visible:=true;
              e.WorkBooks.close;
  Application.ProcessMessages;
end;

цикл по файлам работает, на данным из ячейки нет..не могу догнать в чем ошибка


 
Thrashead   (2009-09-22 16:43) [1]

1) после строки
for i:=0 to Memo1.Lines.Count - 1 do
блок операторов заключить в begin end; иначе не понятно, как вообще "цикл по файлам работает".

2) при использовании "for ..." нет необходимости наращивать счётчик i внутри цикла, for сам "щелкает".

3) возможно, следует (на всякий случай) проверять сначала количество строк в Memo1, а вдруг там пусто?

4) после всей обработки осбободить память: E.Free;

Удачи :)


 
Thrashead   (2009-09-22 17:10) [2]

п.4 - я немного напутал... - Надо Excel.Quit;

Насколько помню, чтобы получить значение ячейки, надо обращаться к Cell, причём по её "числовым координатам". А Range - это нечто другое, а именно диапазон ячеек, например "A1:H8". Если не ошибаюсь, у Range нет свойства Value.

Вообщем, как-то так:

procedure TForm1.Button3Click(Sender: TObject);
var
ExcelApp, WorkSheet: Variant;
SomeValue: String;
i: Integer;
begin
if Memo1.Lines.Count>0 then
 begin
  Excel: CreateOleObject("Excel.Application");
  Excel.Visible:=False;
  for i:=0 to Memo1.Lines.Count-1 do
   begin
    Excel.Workbooks.Open(Memo1.Lines[i]);
    WorkSheet:=Excel.Workbooks[1].WorkSheets[1];
    SomeValue:=VarToStr(WorkSheet.Cells[1,1]);
    ShowMessage(SomeValue);
    Excel.Workbooks.Close;
   end;
  Excel.Quit;
 end;
end;


 
Сергей М. ©   (2009-09-22 17:10) [3]


> осбободить память: E.Free


С чего бы Free ?
Это же не дельфийский объект, чтобы ему фри устраивать)


 
Thrashead   (2009-09-22 17:12) [4]

сергей М.
:) я перепутал малость. бывает.


 
Thrashead   (2009-09-22 17:24) [5]

я ещё добавил бы проверку на существование файла:
...
for i:=0 to Memo1.Lines.Count-1 do
if FileExists(Memo1.Lines[i]) then
 begin
  ...


 
kate158 ©   (2009-09-22 17:27) [6]

что делать если пользователь в эдит добавил адрес не одной ячейки? например d5,H6,g8?


 
Сергей М. ©   (2009-09-22 17:29) [7]

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


 
Thrashead   (2009-09-22 17:29) [8]

хмм...
Через Range можно обратиться и к одной ячейке:
SomeValue:=WorkSheet.Range["A1"].Value;

http://msdn.microsoft.com/en-us/library/microsoft.office.tools.excel.worksheet.range(VS.80).aspx


 
Сергей М. ©   (2009-09-22 17:31) [9]


> Через Range можно обратиться и к одной ячейке


Ему к одной и надо
См.

> нахожу опр ячейку


А юзер, зараза, взял да и ввел не одну)


 
Thrashead   (2009-09-22 17:34) [10]

Сергей:
и как этот ввод запретить? адрес ячейки ведь до IV65536. Маску делать?
Может
try ... except
?


 
Сергей М. ©   (2009-09-22 17:36) [11]


> Thrashead   (22.09.09 17:34) [10]


Обработка OnChange + перехват операции вставки текста в Edit-контрол из буфера обмена


 
kate158 ©   (2009-09-22 17:38) [12]

сорри..
мне надо не одну..
пользователь может ввести как D1, как d1:d5, как d1,g5,h6....


 
Thrashead   (2009-09-22 17:41) [13]

:)
становится интереснее


 
Thrashead   (2009-09-22 17:45) [14]

1) если в строке нет запятых и двоеточий, то обращаемся к ячейке, полагая, что введён корректный адрес;
2) если нет запятых, но есть одно двоеточие, то обращаемся к Range, полагая, что введён корректный диапазон;
3) если нет двоеточий, но есть запятая (-ые), то разбиваем на подстроки, и далее в цикле обрабатываем указанные ячейки.
хмм...


 
kate158 ©   (2009-09-22 17:55) [15]

самое интересное - 3)
+ пользователь вводит русские буквы
+ лишние пробелы...


 
Thrashead   (2009-09-22 18:05) [16]

русские буквы:
1) строку в верхний регистр;
2) если подстрока содержит символы ascii 48..57 или 65..90, то всё норм, иначе - в топку такую подстроку.

лишние пробелы:
написать доп.функцию для замены строки1 на строку2, например:
Replace(" ","");
заменить пробел на пустую строку.


 
Thrashead   (2009-09-22 18:07) [17]

Replace( где менять, что менять, на что менять );

ps. что за программа будет в итоге?


 
Сергей М. ©   (2009-09-22 19:12) [18]


> мне надо не одну


Если "не одну", то что тогда ты собрался записывать в Блокнот ? И в каком виде ?


 
kate158 ©   (2009-09-23 09:04) [19]

объясняю. программа будет выцеплять из excel файлов ячейчки, ктр укажет пользователь и добавлять информацию в виде "название excel файла" + "значение выбранной ячейки (ячеек)" в блокнот


 
Сергей М. ©   (2009-09-23 09:12) [20]

Т.е. в результате требуется получить

c:\path1\file1.xls "Значение ячейки D5" "Значение ячейки H6" "Значение ячейки G8"
c:\path2\file2.xls "Значение ячейки D5" "Значение ячейки H6" "Значение ячейки G8"

или

c:\path1\file1.xls "Значение ячейки D5"
c:\path1\file1.xls "Значение ячейки H6"
c:\path1\file1.xls "Значение ячейки G8"
c:\path2\file2.xls "Значение ячейки D5"
c:\path2\file2.xls "Значение ячейки H6"
c:\path2\file2.xls "Значение ячейки G8"

?


 
kate158 ©   (2009-09-23 09:20) [21]

c:\path1\file1.xls "Значение ячейки D5" "Значение ячейки H6" "Значение ячейки G8"
c:\path2\file2.xls "Значение ячейки D5" "Значение ячейки H6" "Значение ячейки G8"


 
Сергей М. ©   (2009-09-23 09:22) [22]

Ну и какие проблемы ?


 
kate158 ©   (2009-09-23 09:24) [23]

в зависимости от того, скока ячеек выбрал пользователь.
если D1,G5, то
c:\path1\file1.xls "Значение ячейки D1" "Значение ячейки G5"
c:\path1\file2.xls "Значение ячейки D1" "Значение ячейки G5"
...
если D1:D5, то
c:\path1\file1.xls "Значение ячейки D1" "Значение ячейки D2" "Значение ячейки D3" "Значение ячейки D4" "Значение ячейки D5"
c:\path1\file2.xls "Значение ячейки D1" "Значение ячейки D2" "Значение ячейки D3" "Значение ячейки D4" "Значение ячейки D5"
...
если D1 то
c:\path1\file1.xls "Значение ячейки D1"
c:\path1\file2.xls "Значение ячейки D1"
...


 
Сергей М. ©   (2009-09-23 09:27) [24]


> kate158 ©   (23.09.09 09:24) [23]


Ценнейшее уточнение)

Ну а проблемы-то в чем заключаются ?


 
kate158 ©   (2009-09-23 09:31) [25]

кто говорил про проблемы?
ответ на 17 и 18 посты
уже программлю спасибо


 
kate158 ©   (2009-09-23 11:07) [26]

блин. тут еще добавилась тема. пользователь может ввести диапазон как D1,G4,F3:F8...


 
kate158 ©   (2009-09-23 11:08) [27]

как можно это все упростить? может на форму кинуть эдиты для фиксированного ввода ячеек?


 
Сергей М. ©   (2009-09-23 11:30) [28]

Ты же сказал что проблем нет ?)


 
kate158 ©   (2009-09-23 11:40) [29]

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


 
Сергей М. ©   (2009-09-23 11:43) [30]

Нафих, спрашивается, нужно такое ТЗ, которое меняется по чьему-то сиюсекундному капризу ?)

Да и проблемы-то что-то не видно)


 
Сергей М. ©   (2009-09-23 11:45) [31]


> F3:F8


Ты не знаешь как "превратить"
F3:F8
в
F3, F4, F5, F6, F7, F8
?
Или где ?)


 
Thrashead   (2009-09-23 14:16) [32]

kate158:
не сомневаюсь, это будет Великая Программа. Спрашивал-то не про конкретную функцию работы с Excel, а в целом: что за проект, для чего и т.д. Для общего представления, о чём идёт речь.

Совет по ТЗ.
Составили, утвердили - и только потом программирование.
Если у заказчика Просветление - все изменения в следующей версии, билде и т.п. Желательно.

По поводу ввода адресов ячеек.
См. пост [14]. Мне кажется, осуществимо. Анализ строки не так уж сложен.
+ пост [31] - тоже не сложно.


 
Сергей М. ©   (2009-09-23 14:25) [33]


> Анализ строки не так уж сложен


Можно даже вообще ничего не анализировать.
Просто пока не поздно согласовать с Заказчиком предложение по изменению ТЗ в части способов указания юзером интересующих его диапазонов.
Вряд ли юзер будет против варианта интерактивного выбора интересующих его ячеек или диапазонов прямо на листе рабочей книги, вместо тупого набивания координат в Еdit"е.


 
kate158 ©   (2009-09-24 11:16) [34]

[31]
собственно, как "превратить"
F3:F8
в
F3, F4, F5, F6, F7, F8
?


 
Сергей М. ©   (2009-09-24 11:49) [35]


> kate158 ©   (24.09.09 11:16) [34]


У самого-то хоть какие-нибудь мысли на сей счет есть ?
Тривиальная же задача ..


 
kate158 ©   (2009-09-24 12:35) [36]

у самой (:))) мысли есть. но хочу других.
значит, так:
1.кинуть на форму 4 едита и забивать адреса ячеек вручную. типа такого:
 Edit1.Text+Edit2.Text+":"+Edit3.Text+Edit4.Text
далее цикл по Edit2 и Edit4..
2.одно поле едит.искать символ ":" типа
If Pos(":",Edit1.Text)<>0 then , вот что далее пока мысль не идет. тоже может выцеплять число и по нему  циклом идти..
может что еще можно придумать..


 
Сергей М. ©   (2009-09-24 12:41) [37]


> у самой


А, ну да .. Миль пардон)

"Ах, графиня, на что Вам судьбина жестокая ?" (С) МВ


> 2.одно поле едит.искать символ ":"


Угу.


> может выцеплять число и по нему  циклом идти


Угу.


 
Сергей М. ©   (2009-09-24 12:44) [38]

Ты [33] читала ?)


 
kate158 ©   (2009-09-24 13:28) [39]

>[38]
читала.это будет завтра.))


 
Сергей М. ©   (2009-09-24 13:36) [40]


> это будет завтра


В смысле ?)


 
Thrashead   (2009-09-24 13:36) [41]

function FunctionX(s: String): String;
var
i, p, n1, n2: Integer = 0;                            
t, t1, t2, t11, t21, t3: String = "";
procedure GetParts(a: String; var b: String; var c: Integer);
var
 j: Integer = 0;
 FDP: Integer = 0; // First Digit Position                                                                                  
 tt: String = "";                          
begin
 b:="";
 c:=0;
 if a<>"" then                                
  for j:=1 to Length(a) do
   if a[j] in ["0".."9"] then                                                                                            
    if FDP=0 then FDP:=j;
 if FDP>1 then
  begin
   b:=Copy(a,1,FDP-1);
   try
    c:=StrToInt(Copy(a,FDP,Length(a)-FDP+1));                                                        
   except
   end;              
  end;            
end;
function GetNextLetters(a: String): String;
var
 tt: String;
 j: Integer;
 IncLetter: Boolean = True;                                                                        
begin
 tt:=UpperCase(a);
 Result:=tt;                          
 for j:=Length(tt) downto 1 do
  begin
   if IncLetter then
    if tt[j] in ["A".."Z"] then                                                                      
     if tt[j]="Z" then
      begin                          
       Result[j]:="A";  
       if j=1 then Result:="A"+Result;
      end                  
     else
      begin
       Result[j]:=Chr(Ord(Result[j])+1);
       IncLetter:=False;                                            
      end;                
  end;            
end;            
begin                        
Result:="";
p:=Pos(":",s);
if (p>0) and (p<Length(s)) then                            
 begin
  t:=UpperCase(s);
  t1:=Copy(t,1,p-1);
  t2:=Copy(t,p+1,Length(t)-p);
  if (t1<>"") and (t2<>"") then
   begin                          
    GetParts(t1,t11,n1);
    GetParts(t2,t21,n2);
// TEST     Result:=t1+"-"+t11+"-"+IntToStr(n1)+" / "+t2+"-"+t21+"-"+IntToStr(n2);
    if (t11<>"") and (t21<>"") and (n1>0) and (n2>0) and (n1<=n2) then
     if (t11<t21) then
      begin
       t3:=t11;
       i:=n1;                      
       while t3<>t21 do
        begin
         for i:=n1 to n2 do                                                                      
          Result:=Result+t3+IntToStr(i)+",";                                                                                      
         t3:=GetNextLetters(t3);                                                                                              
        end;
       for i:=n1 to n2 do Result:=Result+t21+IntToStr(i)+",";                                                        
       Result:=Copy(Result,1,Length(Result)-1);                                                                                          
      end;                
     if (t11=t21) and (n1<n2) then
      begin
       for i:=n1 to n2 do Result:=Result+t11+IntToStr(i)+",";
       Result:=Copy(Result,1,Length(Result)-1);                                                                                          
      end;  
   end;
 end;              
end;
 
procedure Button1OnClick(Sender: TfrxComponent);
begin                                                  
Edit1.Text:=FunctionX("a1:aaa3");          
end;


 
Thrashead   (2009-09-24 13:41) [42]

сейчас, силя на работе, наваял кусок кода.
протестировано в fastreport.

много букв, т.к. сделаны некоторые проверки на возможные ошибки в строке.

+обрабатывает excel"евские AA,AB, AZ, AAA и т.п.
знаю, что в экселе нет AAA (IV предел) - но сделал универсально.

применимо только к строкам с двоеточием (см. код).

хз что ещё добавить.
вроде работает.


 
Thrashead   (2009-09-24 13:42) [43]

хммм... опечатка. "сиДя на работе".


 
kate158 ©   (2009-09-24 14:54) [44]

Сергей М. спасибо!
Thrashead спасибо! код - то, что нужно.
:)


 
Thrashead   (2009-09-24 15:01) [45]

Наздоровье :)
Ещё интересные задачки будут?



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

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

Наверх




Память: 0.6 MB
Время: 0.023 c
15-1252331396
картман
2009-09-07 17:49
2009.11.08
Словоформы


13-1124174625
inspirion
2005-08-16 10:43
2009.11.08
IIS 5.1 и ASP.NET


15-1252510755
TUser
2009-09-09 19:39
2009.11.08
Опрос (ну или явка с повинной :))


3-1229276722
Kabal
2008-12-14 20:45
2009.11.08
Как сохранить результат SQL запроса в таблицу Paradox?


2-1253783148
Nutz
2009-09-24 13:05
2009.11.08
передача файлов в пассивном режиме FTP