Ir al contenido


Foto

Error con Word Automation con Open en Lazarus


  • Por favor identifícate para responder
11 respuestas en este tema

#1 wangel

wangel

    Newbie

  • Miembros
  • Pip
  • 6 mensajes

Escrito 21 mayo 2014 - 06:49

Cordial saludo
Tengo un problema a la hora de usar el método Open de los word automation en Lazarus, este es mi código:



delphi
  1. for i:=0 to CantidadDeArchivos-1 do
  2. begin
  3. RutaArchivoActual:=ExtractFilePath(Application.exename)+carpeta+'\'+ListaDeArchivos[i]+'.doc';
  4. dw.Documents.Open(RutaArchivoActual);
  5. end;



Anteriormente haciendo pruebas abrí un documento por ejemplo:



delphi
  1. dw.Documents.Open('C:/documento.doc');


dentro del ciclo for, y lo hace correctamente, pero cuando pongo el nombre del archivo como una variable como es RutaArchivoActual, me lanza el error "espacio de almacenamiento insuficiente para completar esta información". Me puse a investigar en el foro y encontré que cuando el nombre de archivo es variable, se le ponen más parámetros a Open, por ejemplo:




delphi
  1. Document := dw.Documents.Open(NombreDoc,EmptyParam,EmptyParam,EmptyParam,EmptyParam,EmptyParam,EmptyParam,false);



Pero cuando hago esto, lazarus me dice que no reconoce a EmptyParam, que no está definido; luego investigué en el boletín 6 de rinconcito delphi y da un ejemplo:



delphi
  1. dw.Documents.Open(RutaArchivoActual,0,0,0,'','',1,'','',0);



pero al hacer esto, me sale un error diciendo que "word ha dejado de funcionar", lo mismo pasa cuando intento usar otras opciones como.



delphi
  1. dw.Documents.Open(RutaArchivoActual,null,null,null);



Mi interés es que el nombre de archivo sea variable porque mi aplicación debe hacer una búsqueda dentro de muchos archivos word.
De antemano gracias por sus respuestas y su interés.
  • 0

#2 Sergio

Sergio

    Advanced Member

  • Moderadores
  • PipPipPip
  • 1.092 mensajes
  • LocationMurcia, España

Escrito 22 mayo 2014 - 04:03

Yo utilizo esto:



delphi
  1. Programa:= CreateOleObject('Word.Application');
  2. Document:= Programa.Documents.Open(string(FileName),,,,,,,,,,,true);



Si quieres mas cosas tengo una unit para acceder a documentos de textos, vale para MSOffice, LibreOffice y OpenOffice, es similar a otra que tengo para Excel, pero esta es mucho más simple y hace poquitas cosas:



delphi
  1. // *********************************************
  2. // ** Object for dual WordProcessing managing **
  3. // ** using Word or OpenOffice automaticaly  **
  4. // ** By: Sergio Hernandez                    **
  5. // ** oficina(at)hcsoft.net, CopyLeft 2004    **
  6. // ** Version 0.3 20-10-2009 (DDMMYYYY)      **
  7. // ** Use it freely, change it, etc.          **
  8. // *********************************************
  9.  
  10. {EXAMPLE OF USE
  11.   //Create object: We have two flavours:
  12.   //(A) from an existing file...
  13.   TxtDoc:= TDocumentoTexto.create(OpenDialog.FileName, false);
  14.   //(B) from a blank document...
  15.   TxtDoc:= TDocumentoTexto.create(thcOpenOffice, true); //OpenOffice doc if possible, please
  16.   TxtDoc.FileName:= 'C:\MyNewDoc'; //Needs a file name before you SaveDoc!
  17.   //--end of creation.
  18.   //Change a text (search&replace)
  19.   TxtDoc.ChangeOneValue('<MyClient>', 'Cocoa company, ltd.');
  20.   //Preview print...
  21.   TxtDoc.ShowPrintPreview
  22.   TxtDoc.PrintDoc;
  23.   TxtDoc.SaveDoc;
  24.   TxtDoc.SaveToPDF('C:\MyPDF.pdf');
  25.   TxtDoc.Free;
  26. }
  27.  
  28. {ABOUT CONVERTING DOC TO PDF:
  29.   //Force opening the .doc file with OOo like this:
  30.   TxtDoc:= TDocumentoTexto.create(thcOpenOffice, true);
  31.   TxtDoc.LoadDoc('C:\MyWord.doc');
  32.   //Now that OOo has imported the .doc, convert it:
  33.   TxtDoc.SaveToPDF('C:\MyPDF.pdf');
  34.   TxtDoc.Free;
  35. }
  36.  
  37. {HISTORIY:
  38. V0.3 - SaveToPDF for OpenOffice added from www.oooforum.org/forum/viewtopic.phtml?t=22344
  39. V0.2 - WaitForIddle added to avoid Word behavior (saving before completing work)
  40. V0.1 - Initial version, it works ok.
  41. }
  42.  
  43. {TODO LIST:
  44.   -No functions to add text, change font, bold, etc.
  45.   -Can I know the OOo writer printing status like in Word?
  46.   -Can I know if Word/Writer is doing something in background?
  47. }
  48.  
  49. unit UDocumentoTexto;
  50.  
  51. interface
  52.  
  53. uses Variants, SysUtils, ComObj, Classes, Launch;
  54.  
  55. //thcError: Tried to open but both failes
  56. //thcNone:  Haven't tried still to open
  57. type TTipoDoc = (thcError, thcNone, thcWord, thcOpenOffice);
  58.  
  59. type TDocumentoTexto = class(TObject)
  60. private
  61.   fVisible:  boolean;
  62.   //Program loaded stuff...
  63.   procedure  LoadProg;
  64.   procedure  CloseProg;
  65.   function  GetProgLoaded: boolean;
  66.   procedure  NewDoc;
  67.   procedure  LoadDoc;
  68.   procedure  CloseDoc;
  69.   function  GetDocLoaded: boolean;
  70.   function  GetIsWord: boolean;
  71.   function  GetIsOpenOffice: boolean;
  72.   procedure  SetVisible(v: boolean);
  73.   //OpenOffice only stuff...
  74.   function  FileName2URL(FileName: string): string;
  75.   procedure  ooDispatch(ooCommand: string; ooParams: variant);
  76.   function  ooCreateValue(ooName: string; ooData: variant): variant;
  77.   function  isNullEmpty(thisVariant: Variant): Boolean;
  78. public
  79.   Tipo: TTipoDoc;        //Witch program was used to manage the doc?
  80.   FileName:    string;    //In windows FileName format C:\MyDoc.XXX
  81.   Programa:    variant;  //Word or OpenOfice instance created.
  82.   DeskTop:    variant;  //OpenOffice desktop reference (not used now).
  83.   Document:    variant;  //Document opened.
  84.   //Object internals...
  85.   constructor  Create(Name: string; MakeVisible: boolean); overload;
  86.   constructor  Create(MyTipo: TTipoDoc; MakeVisible: boolean); overload;
  87.   destructor  Destroy; override;
  88.   //Program loaded stuff...
  89.   function    SaveDoc: boolean;
  90.   function    SaveToPDF(FileName: string): boolean;
  91.   function    PrintDoc: boolean;
  92.   procedure    ShowPrintPreview;
  93.   property    ProgLoaded: boolean    read GetProgLoaded;
  94.   property    DocLoaded:  boolean    read GetDocLoaded;
  95.   property    IsWord: boolean        read GetIsWord;
  96.   property    IsOpenOffice: boolean  read GetIsOpenOffice;
  97.   property    Visible: boolean        read fVisible          write SetVisible;
  98.   //Special function (Search & Replace)
  99.   procedure    ChangeOneValue(SearchTxt, ReplaceTxt: String; Headers: boolean = true);
  100.   //Wait until word end doing its things
  101.   function    WaitForIddle(MaxSec: double = 30): double;
  102. end;
  103.  
  104. var
  105.   CoInitFlags: Integer = -1;
  106.  
  107. const
  108.   SearchAll: integer = 2; //Word search_for_all (0=None, 1=Once, 2=All)
  109.  
  110. implementation
  111.  
  112. // ************************
  113. // ** Create and destroy **
  114. // ************************
  115.  
  116. //Create with an empty doc of requested type (use thcWord, thcOpenOffice)
  117. //Remember to define FileName before calling to SaveDoc
  118. constructor TDocumentoTexto.Create(MyTipo: TTipoDoc; MakeVisible: boolean);
  119. var
  120.   i: integer;
  121.   IsFirstTry: boolean;
  122. begin
  123.   //Close all opened things first...
  124.   CloseDoc;
  125.   CloseProg;
  126.   //I will try to open twice, so if Word fails, OpenOffice is used instead
  127.   IsFirstTry:= true;
  128.   for i:= 1 to 2 do begin
  129.     //Try to open OpenOffice...
  130.     if (MyTipo = thcOpenOffice) or (MyTipo = thcNone)then begin
  131.       try
  132.         Programa:= CreateOleObject('com.sun.star.ServiceManager');
  133.       except
  134.       end;
  135.       if ProgLoaded then begin
  136.         Tipo:= thcOpenOffice;
  137.         break;
  138.       end else begin
  139.         if IsFirstTry then begin
  140.           //Try Excel as my second choice
  141.           MyTipo:= thcWord;
  142.           IsFirstTry:= false;
  143.         end else begin
  144.           //Both failed!
  145.           break;
  146.         end;
  147.       end;
  148.     end;
  149.     //Try to open Word...
  150.     if (MyTipo = thcWord) or (MyTipo = thcNone) then begin
  151.       try
  152.         Programa:= CreateOleObject('Word.Application');
  153.       except
  154.       end;
  155.       if ProgLoaded then begin
  156.         Tipo:= thcWord;
  157.         break;
  158.       end else begin
  159.         if IsFirstTry then begin
  160.           //Try OpenOffice as my second choice
  161.           MyTipo:= thcOpenOffice;
  162.           IsFirstTry:= false;
  163.         end else begin
  164.           //Both failed!
  165.           break;
  166.         end;
  167.       end;
  168.     end;
  169.   end;
  170.   //Was it able to open any of them?
  171.   if Tipo = thcNone then begin
  172.     Tipo:= thcError;
  173.     raise Exception.Create('TDocumentoTexto.create failed, may be no Office is installed?');
  174.   end;
  175.   //Add a blank document...
  176.   fVisible:= MakeVisible;
  177.   NewDoc;
  178. end;
  179.  
  180. constructor TDocumentoTexto.Create(Name: string; MakeVisible: boolean);
  181. begin
  182.   //Close all opened things first...
  183.   CloseDoc;
  184.   CloseProg;
  185.   Tipo:= thcNone;
  186.   //Store values...
  187.   FileName:= Name;
  188.   //Open program and document...
  189.   LoadProg;
  190.   LoadDoc;
  191.   //Visible?
  192.   Visible:= MakeVisible;
  193. end;
  194.  
  195. destructor TDocumentoTexto.Destroy;
  196. begin
  197.   CloseProg;
  198.   inherited;
  199. end;
  200.  
  201. // *************************
  202. // ** Loading the program **
  203. // ** Word or OpenOffice  **
  204. // *************************
  205.  
  206. procedure TDocumentoTexto.LoadProg;
  207. begin
  208.   if ProgLoaded then CloseProg;
  209.   if (UpperCase(ExtractFileExt(FileName))='.DOC') then begin
  210.     //Word is the primary choice...
  211.     try
  212.       Programa:= CreateOleObject('Word.Application');
  213.     except end;
  214.     if ProgLoaded then Tipo:= thcWord;
  215.   end;
  216.   //Not lucky with Word? Another filetype? Let's go with OpenOffice...
  217.   if Tipo = thcNone then begin
  218.     //Try with OpenOffice...
  219.     try
  220.       Programa:= CreateOleObject('com.sun.star.ServiceManager');
  221.     except end;
  222.     if ProgLoaded then Tipo:= thcOpenOffice;
  223.   end;
  224.   //Still no program loaded?
  225.   if not ProgLoaded then begin
  226.     Tipo:= thcError;
  227.     raise Exception.Create('TDocumentoTexto.LoadProg failed, may be no Office is installed?');
  228.   end;
  229. end;
  230.  
  231. procedure TDocumentoTexto.CloseProg;
  232. begin
  233.   if not Visible then CloseDoc;
  234.   if ProgLoaded then begin
  235.     try
  236.       if IsWord then begin
  237.         Programa.Quit;
  238.         Programa:= Null;
  239.       end;
  240.       if IsOpenOffice then begin
  241.         Desktop.Dispose;
  242.         Desktop:= unassigned;
  243.         Programa.Dispose;
  244.       end;
  245.       Programa:= Unassigned;
  246.     except end;
  247.   end;
  248.   Tipo:= thcNone;
  249. end;
  250.  
  251. //Is there any prog loaded? Witch one?
  252. function TDocumentoTexto.GetProgLoaded: boolean;
  253. begin
  254.   result:= not isNullEmpty(Programa);
  255. end;
  256. function  TDocumentoTexto.GetIsWord: boolean;
  257. begin
  258.   result:= (Tipo=thcWord);
  259. end;
  260. function  TDocumentoTexto.GetIsOpenOffice: boolean;
  261. begin
  262.   result:= (Tipo=thcOpenOffice);
  263. end;
  264.  
  265. // ************************
  266. // ** Loading a document **
  267. // ************************
  268.  
  269. procedure TDocumentoTexto.NewDoc;
  270. var ooParams: variant;
  271. begin
  272.   //Is the program running? (Word or OpenOffice)
  273.   if not ProgLoaded then raise Exception.Create('No program loaded for the new document.');
  274.   //Is there a doc already loaded?
  275.   CloseDoc;
  276.   DeskTop:= Unassigned;
  277.   //OK, now try to create the doc...
  278.   if IsWord then begin
  279.     Programa.WorkBooks.Add;
  280.     Programa.Visible:= Visible;
  281.     Document:= Programa.ActiveWorkBook;
  282.   end;
  283.   if IsOpenOffice then begin
  284.     Desktop:=  Programa.CreateInstance('com.sun.star.frame.Desktop');
  285.     //Optional parameters (visible)...
  286.     ooParams:=    VarArrayCreate([0, 0], varVariant);
  287.     ooParams[0]:= ooCreateValue('Hidden', false); // çç not Visible);
  288.     //Create the document...
  289.     Document:= Desktop.LoadComponentFromURL('private:factory/swriter', '_blank', 0, ooParams);
  290.   end;
  291. end;
  292.  
  293. procedure TDocumentoTexto.LoadDoc;
  294. var ooParams: variant;
  295. begin
  296.   if FileName='' then exit;
  297.   //Is the program running? (Word or OpenOffice)
  298.   if not ProgLoaded then LoadProg;
  299.   //Is there a doc already loaded?
  300.   CloseDoc;
  301.   DeskTop:= Unassigned;
  302.   //OK, now try to open the doc...
  303.   if IsWord then begin
  304.     Document:= Programa.Documents.Open(string(FileName),,,,,,,,,,,true);
  305.   end;
  306.   if IsOpenOffice then begin
  307.     Desktop:=  Programa.CreateInstance('com.sun.star.frame.Desktop');
  308.     //Optional parameters (visible)...
  309.     ooParams:=    VarArrayCreate([0, 0], varVariant);
  310.     ooParams[0]:= ooCreateValue('Hidden', false); //Should be "not Visible" but didn't work ok
  311.     //Open the document...
  312.     Document:= Desktop.LoadComponentFromURL(FileName2URL(FileName), '_blank', 0, ooParams);
  313.     if isNullEmpty(Document) then
  314.       raise Exception.Create('Could load the  document "'+FileName+'".');
  315.   end;
  316.   if Tipo=thcNone then
  317.     raise Exception.Create('Could load the document "'+FileName+'". No Word processor installed?.');
  318. end;
  319.  
  320. function TDocumentoTexto.SaveDoc: boolean;
  321. begin
  322.   result:= false;
  323.   if DocLoaded then begin
  324.     if IsWord then begin
  325.       Document.Save;
  326.       result:= true;
  327.     end;
  328.     if IsOpenOffice then begin
  329.       //There is another method, more powerfull, see SaveToPDF function.
  330.       Document.Store;
  331.       result:= true;
  332.     end;
  333.   end;
  334. end;
  335.  
  336. //If you are using OOo, you can export to PDF directly.
  337. //In word, the only choice is to use a PDF printer, out of our scope here!
  338. //NOTE: If you open a HTML in OOo, the param 0 need to be diferent as commented
  339. //Code refactored from an example by Ryan at:
  340. //  http://www.oooforum.org/forum/viewtopic.phtml?t=22344
  341. function TDocumentoTexto.SaveToPDF(FileName: string): boolean;
  342. var ooParams: variant;
  343. begin
  344.   result:= false;
  345.   if DocLoaded then begin
  346.     if IsOpenOffice then begin //Word can't export to PDF!
  347.       ooParams:= VarArrayCreate([0, 0], varVariant);
  348.       //If the doc loaded is a HTML, you should use this param[0] instead:
  349.       //ooParam[0]:= ooCreateValue('FilterName', 'writer_web_pdf_Export')
  350.       ooParams[0]:= ooCreateValue('FilterName', 'writer_pdf_Export');
  351.       Document.StoreToURL(FileName2URL(FileName), ooParams);
  352.     end;
  353.   end;
  354. end;
  355.  
  356. //Print the Doc...
  357. function TDocumentoTexto.PrintDoc: boolean;
  358. var ooParams: variant;
  359. begin
  360.   result:= false;
  361.   if DocLoaded then begin
  362.     if IsWord then begin
  363.       Document.PrintOut;
  364.       while Programa.BackgroundPrintingStatus > 0 do
  365.         sleep(500);
  366.       result:= true;
  367.     end;
  368.     if IsOpenOffice then begin
  369.       ooParams:=  VarArrayCreate([0, 0], varVariant);
  370.       ooParams[0]:= ooCreateValue('Wait', true);
  371.       Document.Print(ooParams);
  372.       //Can't know printing status (maybe it is possible)
  373.       //So wait for process to iddle (under 0.5% CPU)
  374.       WaitForIddle;
  375.       result:= true;
  376.     end;
  377.   end;
  378. end;
  379.  
  380. procedure TDocumentoTexto.ShowPrintPreview;
  381. begin
  382.   if DocLoaded then begin
  383.     //Force visibility of the doc...
  384.     Visible:= true;
  385.     if IsWord then
  386.       Document.PrintOut(,,,true);
  387.     if IsOpenOffice then
  388.       ooDispatch('.uno:PrintPreview', Unassigned);
  389.   end;
  390. end;
  391.  
  392. procedure TDocumentoTexto.SetVisible(v: boolean);
  393. begin
  394.   if DocLoaded and (v<>fVisible) then begin
  395.     if IsWord then
  396.       Programa.Visible:= v;
  397.     if IsOpenOffice then begin
  398.       Document.getCurrentController.getFrame.getContainerWindow.setVisible(v);
  399.     end;
  400.     fVisible:= v;
  401.   end;
  402. end;
  403.  
  404. procedure TDocumentoTexto.CloseDoc;
  405. begin
  406.   if DocLoaded then begin
  407.     //Close it...
  408.     try
  409.       if IsOpenOffice then Document.Dispose;
  410.       if IsWord      then Document.close;
  411.     except end;
  412.     //Clean up "pointer"...
  413.     Document:= Null;
  414.   end;
  415. end;
  416.  
  417. function TDocumentoTexto.GetDocLoaded: boolean;
  418. begin
  419.   result:= not isNullEmpty(Document);
  420. end;
  421.  
  422. procedure TDocumentoTexto.ChangeOneValue(SearchTxt, ReplaceTxt: String; Headers: boolean = true);
  423. var  j, Paso: integer;
  424.     Txt, Busca, Reemp: string;
  425.     ooBuscador: variant;
  426. begin
  427.   case Tipo of
  428.   thcWord: begin
  429.       //Word can't replace with a text longer than 250!
  430.       if length(ReplaceTxt) < 250 then begin
  431.         Programa.ActiveDocument.Content.Find.Execute(SearchTxt, true, false, false, false, false,,,, ReplaceTxt, SearchAll);
  432.         if Headers then begin
  433.           //Search in page header...
  434.           Programa.ActiveWindow.ActivePane.View.SeekView:=  9; //9 = wdSeekCurrentPageHeader
  435.           Programa.Selection.Find.Execute(SearchTxt, true, false, false, false, false,,,,ReplaceTxt,SearchAll);
  436.           //Search on footer...
  437.           Programa.ActiveWindow.ActivePane.View.SeekView:= 10; //10 = wdSeekCurrentPageFooter
  438.           Programa.Selection.Find.Execute(SearchTxt, true, false, false, false, false,,,,ReplaceTxt,SearchAll);
  439.         end;
  440.         //You can wait for Word to finish 0.1 secs. uncomenting next line...
  441.         //sleep(100);
  442.         //...but calling WaitForIddle after all your replaces is a better choice!
  443.       end else begin
  444.         //I have to "chop" the text into pieces of max. 240 chars!
  445.         //NOTE: Coping from array N[] to D[] can make a DLL run out of memory
  446.         //and raise rare errors, so I make it char by char!
  447.         Busca:= ''; for j:= 1 to Length(SearchTxt)  do Busca:= Busca+SearchTxt[j];
  448.         Reemp:= ''; for j:= 1 to Length(ReplaceTxt) do Reemp:= Reemp+ReplaceTxt[j];
  449.         Paso:= 1;
  450.         repeat
  451.           Txt:=  copy(Reemp,1,240);
  452.           Reemp:= copy(Reemp,241,9999);
  453.           if (Reemp<>'') then
  454.             Txt:= Txt+'[@#@'+IntToStr(Paso)+']';
  455.           Programa.ActiveDocument.Content.Find.Execute(Busca,true,false,false,false,false,,,,Txt,SearchAll);
  456.           Busca:= '[@#@'+IntToStr(Paso)+']';
  457.           inc(Paso);
  458.           //Need to wait for Word to finish before processing the next txt piece
  459.           sleep(100);
  460.         until (Reemp='');
  461.       end;
  462.     end;
  463.   thcOpenOffice: begin
  464.       if isNullEmpty(Document) then
  465.         raise Exception.Create('No text document loaded');
  466.       ooBuscador:= Document.createReplaceDescriptor;
  467.       ooBuscador.SearchString:=  SearchTxt;
  468.       ooBuscador.ReplaceString:= ReplaceTxt;
  469.       Document.ReplaceAll(ooBuscador);
  470.     end;
  471.   end;
  472. end;
  473.  
  474. //Wait for Word to end up with all instruction we have through at it.
  475. //As Word diggest them asincronous, you never know if you are finish
  476. //and you can end up saving BEFORE all previous commands are done!
  477. //It detects it by measuring the proc %CPU usage until it drops below 0.5%
  478. function TDocumentoTexto.WaitForIddle(MaxSec: double = 30): double;
  479. var ProcName: string;
  480. begin
  481.   //Process Name...
  482.   if Tipo=thcWord then ProcName:= 'WINWORD.EXE'
  483.   else                ProcName:= 'swriter.exe';
  484.   //Wait for the %CPU to drop below 0.5%
  485.   result:= WaitExeIddle(ProcName, 1, MaxSec);
  486. end;
  487.  
  488. // ***************************
  489. // ** OpenOffice only stuff **
  490. // ***************************
  491.  
  492. //Change 'C:\File.txt' into 'file:///c:/File.txt' (for OpenOffice OpenURL)
  493. function TDocumentoTexto.FileName2URL(FileName: string): string;
  494. begin
  495.   result:= '';
  496.   if LowerCase(copy(FileName,1,8))<>'file:///' then
  497.     result:= 'file:///';
  498.   result:= result + StringReplace(FileName, '\', '/', [rfReplaceAll, rfIgnoreCase]);
  499. end;
  500.  
  501. function TDocumentoTexto.ooCreateValue(ooName: string; ooData: variant): variant;
  502. var
  503.   ooReflection: variant;
  504. begin
  505.   if IsOpenOffice then begin
  506.     ooReflection:= Programa.createInstance('com.sun.star.reflection.CoreReflection');
  507.     ooReflection.forName('com.sun.star.beans.PropertyValue').createObject(result);
  508.     result.Name := ooName;
  509.     result.Value:= ooData;
  510.   end else begin
  511.     raise Exception.Create('ooValue imposible to create, load OpenOffice first!');
  512.   end;
  513. end;
  514.  
  515. procedure TDocumentoTexto.ooDispatch(ooCommand: string; ooParams: variant);
  516. var
  517.   ooDispatcher, ooFrame: variant;
  518. begin
  519.   if DocLoaded and IsOpenOffice then begin
  520.     if (VarIsEmpty(ooParams) or VarIsNull(ooParams)) then
  521.       ooParams:= VarArrayCreate([0, -1], varVariant);
  522.     ooFrame:= Document.getCurrentController.getFrame;
  523.     ooDispatcher:= Programa.createInstance('com.sun.star.frame.DispatchHelper');
  524.     ooDispatcher.executeDispatch(ooFrame, ooCommand, '', 0, ooParams);
  525.   end else begin
  526.     raise Exception.Create('Dispatch imposible, load a OpenOffice doc first!');
  527.   end;
  528. end;
  529.  
  530. function TDocumentoTexto.isNullEmpty(thisVariant: Variant): Boolean;
  531. begin
  532.   Result:= VarIsEmpty(thisVariant) or VarIsNull(thisVariant) or VarIsClear(thisVariant);
  533. end;
  534.  
  535. end.


  • 0

#3 wangel

wangel

    Newbie

  • Miembros
  • Pip
  • 6 mensajes

Escrito 22 mayo 2014 - 06:31

Hola Sergio, gracias por tu respuesta, he probado la primera opción que me indicaste pero me salta el error "Espacio de almacenamiento insuficiente para completar esta operación" y solo estoy cargando un documento, el código de la función quedó así:



delphi
  1. type
  2.   Tresultado=class(TObject)    //clase resultado cuando se encuentra una palabra en el archivo, se guardan sus datos
  3.   NombreArchivo:String;
  4.   TextoVistaPrevia:String;
  5.   Relevancia,EncontradoEnLinea:integer;
  6. end;
  7.  
  8. function TFrmPrincipal.BuscarPalabra(carpeta,frase:String;TipoBusqueda:integer):TObjectList;
  9. var
  10.   renglonTemporal,RutaArchivoActual:string;
  11.   numeroRenglonActual,i,j,m,relevancia,CantidadPalabrasSeparadas,CantidadDeArchivos,numeroDeParrafos:integer;
  12.   resultado:TResultado;
  13.   ListaDeArchivos,PalabrasSeparadas:TStringList;
  14.   dw:Variant;
  15.  
  16. begin
  17.   dw:=CreateOleObject('word.Application');
  18.  
  19.  
  20.   result:=TObjectList.create(true);  //result va a contener la lista de objectos resultado
  21.   ListaDeArchivos:=TStringList.Create;
  22.   PalabrasSeparadas:=TStringList.Create;
  23.  
  24.  
  25.  
  26.   frase:=trim(frase);
  27.   PalabrasSeparadas:=Dividir(frase,' '); //separamos la frase de busqueda en las palabras que la conforman
  28.   CantidadPalabrasSeparadas:=PalabrasSeparadas.Count;
  29.  
  30.   ListaDeArchivos:=ListaArchivos(ExtractFilePath(Application.ExeName)+carpeta,'*.doc',false);
  31.   CantidadDeArchivos:=ListaDeArchivos.Count;
  32.  
  33.   for i:=0 to CantidadDeArchivos-1 do
  34.   begin
  35.     RutaArchivoActual:=ExtractFilePath(Application.exename)+carpeta+'\'+ListaDeArchivos[i]+'.doc';
  36.     //dw.Documents.Open('D:\INFORMACION\Documentos\DOCUMENTOS\CODIGO CIVIL.doc'); //De esta manera funciona OK
  37.     dw.Documents.Open(string(RutaArchivoActual),,,,,,,,,,,true);  // la línea sugerida por Sergio
  38.     numeroRenglonActual:=1;
  39.  
  40.     numeroDeParrafos:=dw.ActiveDocument.paragraphs.count;
  41.  
  42.     while numeroRenglonActual<numeroDeParrafos do
  43.     begin
  44.       numeroRenglonActual:=numeroRenglonActual+1;
  45.       renglonTemporal:=dw.ActiveDocument.paragraphs.item(numeroRenglonActual).range.text;
  46.  
  47.       if TipoBusqueda=1 then  //si se busca una palabra
  48.       begin
  49.         relevancia:=0;
  50.  
  51.         for j:=0 to CantidadPalabrasSeparadas-1 do
  52.         begin
  53.           if AnsiContainsText(renglonTemporal,PalabrasSeparadas[j]) then
  54.             relevancia+=1;
  55.         end;
  56.  
  57.         if relevancia>0 then
  58.         begin
  59.           resultado:=TResultado.Create;  //creamos la instancia de la clase TResultado
  60.           resultado.EncontradoEnLinea:=numeroRenglonActual;
  61.           resultado.TextoVistaPrevia:=renglonTemporal;
  62.  
  63.           resultado.NombreArchivo:=RutaArchivoActual;
  64.           resultado.Relevancia:=relevancia;
  65.  
  66.           result.Add(resultado);
  67.         end;
  68.       end;
  69.     end;
  70.  
  71.     dw.quit;
  72.     ShowMessage('termino la busqueda');
  73.   end;
  74. end;                       



La función lo que hace es buscar una palabra en los archivos .doc de una carpeta, y devolver en un TObjectList la lista de objetos resultado.

Saludos  :)
  • 0

#4 Sergio

Sergio

    Advanced Member

  • Moderadores
  • PipPipPip
  • 1.092 mensajes
  • LocationMurcia, España

Escrito 22 mayo 2014 - 09:53

¿Has comprobado que los ficheros tienen bien el nombre antes de abrirlos?

Eso de añadir .doc a un nombre de fichero suena a que vas a tener ficheros terminados en ".doc.doc", yo añadiría un IF FileExists(FileName) then... por si acaso.

Por cierto, usar una variable o un texto fijo no importa en absoluto, yo siempre uso variables, así que apostaría a que el nombre de fichero que usas está mal de alguna forma.

Otra duda es si el filename ha de ser string o pChar, de memoria no lo sé, pero prueba con pChar(FileName) por si acaso.
  • 0

#5 Sergio

Sergio

    Advanced Member

  • Moderadores
  • PipPipPip
  • 1.092 mensajes
  • LocationMurcia, España

Escrito 22 mayo 2014 - 12:20

Otra duda es si el filename ha de ser string o pChar, de memoria no lo sé, pero prueba con pChar(FileName) por si acaso.


Son String, eso no es!
  • 0

#6 wangel

wangel

    Newbie

  • Miembros
  • Pip
  • 6 mensajes

Escrito 22 mayo 2014 - 12:31

Hola Sergio, en cuanto al nombre de la ruta del archivo, anteriormente ya me había cerciorado de que estuviera bien mediante ShowMessage(), por si las dudas, puse el FileExists y encontró el archivo.

Probando con



delphi
  1. Document:= Programa.Documents.Open(string(FileName),,,,,,,,,,,true);


o


delphi
  1. Document:= Programa.Documents.Open(string(FileName));



me da el mismo error de antes:
"Espacio de almacenamiento insuficiente para completar esta operación"

Gracias por tu interés Sergio
  • 0

#7 wangel

wangel

    Newbie

  • Miembros
  • Pip
  • 6 mensajes

Escrito 22 mayo 2014 - 03:18

Estuve haciendo pruebas poniendo un botón en un formulario y poniendo este código y el error persiste:



delphi
  1. procedure TForm1.Button1Click(Sender: TObject);
  2. var
  3.   dw:Variant;
  4.   RutaArchivoActual:String;
  5. begin
  6. RutaArchivoActual:='D:\INFORMACION\Documentos\DOCUMENTOS\CODIGO CIVIL.doc';
  7. dw:=CreateOleObject('word.Application');
  8. dw.Documents.Open(string(RutaArchivoActual),,,,,,,,,,,true);
  9. end;



lo mismo pasa si pongo


delphi
  1. dw.Documents.Open(string(RutaArchivoActual));


o simplemente


delphi
  1. dw.Documents.Open(RutaArchivoActual);



Al pulsar el botón me salta el mensaje "Espacio de almacenamiento insuficiente para completar esta operación"

Aclaro que estoy usando Lazarus en Windows 7
  • 0

#8 Sergio

Sergio

    Advanced Member

  • Moderadores
  • PipPipPip
  • 1.092 mensajes
  • LocationMurcia, España

Escrito 23 mayo 2014 - 03:02

Igual el problema está en que abres muchos documentos a la vez, igual el primer fichero no da error, pero al llegar al 15 te quedas realmente sin memoria... prueba a poner un solo fichero en la lista a ver.

Piensa que si no cierras el documento y el excel tras cada lectura de fichero, se te pueden acumular en memoria (no se ven en la pantalla pero si en el administrador de tareas) un montón de excels abiertos.
  • 0

#9 wangel

wangel

    Newbie

  • Miembros
  • Pip
  • 6 mensajes

Escrito 23 mayo 2014 - 06:36

Hola Sergio, gracias por tu tiempo, en el último ejemplo que puse:


delphi
  1. procedure TForm1.Button1Click(Sender: TObject);
  2. var
  3.   dw:Variant;
  4.   RutaArchivoActual:String;
  5. begin
  6. RutaArchivoActual:='D:\INFORMACION\Documentos\DOCUMENTOS\CODIGO CIVIL.doc';
  7. dw:=CreateOleObject('word.Application');
  8. dw.Documents.Open(string(RutaArchivoActual),,,,,,,,,,,true);
  9. end;



solo abro un documento y da el mismo error  y siempre estoy pendiente del administrador de tareas antes de ejecutar el programa, si deseas puedes probar con este trozo de código y un botón a ver si te da el mismo error.

Saludos.
  • 0

#10 Sergio

Sergio

    Advanced Member

  • Moderadores
  • PipPipPip
  • 1.092 mensajes
  • LocationMurcia, España

Escrito 26 mayo 2014 - 05:26

No tengo Word ni intención de instalarlo!

Solo uso LibreOffice, incluso para este tipo de pruebas (cuando un cliente me indica que algo le falla, me conecto a su pantalla y compruebo las cosas alli, es imposible tener 20 versiones de Word y/o Excel instaladas y mucho menos de forma legal, así que directamente no lo intento).
  • 0

#11 wangel

wangel

    Newbie

  • Miembros
  • Pip
  • 6 mensajes

Escrito 26 mayo 2014 - 06:32

Bueno, al final tuve que terminar el programa en Delphi porque en Lazarus me daba ese error. Ojalá en un futuro alguien pueda dar respuesta a este problema, ya que me gustaría poder seguir trabajando sobre Lazarus.

Muchas gracias Sergio por tu interés y tu tiempo.
  • 0

#12 poliburro

poliburro

    Advanced Member

  • Administrador
  • 4.945 mensajes
  • LocationMéxico

Escrito 26 mayo 2014 - 07:19

No tengo Word ni intención de instalarlo!

Solo uso LibreOffice, incluso para este tipo de pruebas


Soy de la misma idea amigo, aunque yo uso OpenOffice. La verdad es que la suite es muy buena y generalmente satisface lo que uno requiere.
  • 0




IP.Board spam blocked by CleanTalk.