
Cambiar Texto en un Cuadro de Texto de un Archivo de MS Word
#1
Posted 04 June 2012 - 04:28 AM
Estoy manipulando archivos de Word, soy capaz e buscar y reemplazar Texto y hacer el mismo con tablas insertando el texto que deseo o lo cambiando en la Celda que me apetezca.
Pero tengo un documento que está lleno de Cuadros de Texto adonde la busqueda por el texto no me funciona y tengo que manipular el texto dentro de los mismos.
Estoy ya toda la mañana intentando localizar como hacerlo y no soy capaz.
Alguien tiene idea de como puedo manipular cuadros de texto en MS Word ?
#2
Posted 04 June 2012 - 07:31 AM
Mirate esto (y tiembla): http://word.mvps.org...aceAnywhere.htm
#3
Posted 04 June 2012 - 08:02 AM
Espero que OpenOffice sea más listo para se dejar manipular.
Gracia amigo. Grandes abrazos !!!
#4
Posted 04 June 2012 - 09:37 AM
Un fichero .odt de OpenOffice lo puedes abrir como un .zip, modificar los .txt que lleve dentro cambiandoles palabras, y listo, busca y sustituye sin instalar la aplicación!
Si usas OpenOffice para abrir los .doc, podrás -creo- cambiar el texto sin problemas, esta "rareza" es exclusiva de Word por lo que yo sé, pero al guardarlo de nuevo en .doc te arriesgas a que algún detalle del formato se cambie, en especial si incluye fórmulas, gráficos y esas cosas.
Hazte antes un par de pruebas -o más- de abrir y guardar con OO ficheros típicos de la aplicación, y luego abrirlos con office a ver si algo se te ha cambiado (y usa siempre la versión más actual de openoffice, estos temas los mejoran muy activamente).
#5
Posted 05 June 2012 - 12:55 AM
Yo también trabajo con documentos de OpenOffice, y estas cosas son más... racionales que en MS, por decirlo suavemente.
Un fichero .odt de OpenOffice lo puedes abrir como un .zip, modificar los .txt que lleve dentro cambiandoles palabras, y listo, busca y sustituye sin instalar la aplicación!
Si usas OpenOffice para abrir los .doc, podrás -creo- cambiar el texto sin problemas, esta "rareza" es exclusiva de Word por lo que yo sé, pero al guardarlo de nuevo en .doc te arriesgas a que algún detalle del formato se cambie, en especial si incluye fórmulas, gráficos y esas cosas.
Hazte antes un par de pruebas -o más- de abrir y guardar con OO ficheros típicos de la aplicación, y luego abrirlos con office a ver si algo se te ha cambiado (y usa siempre la versión más actual de openoffice, estos temas los mejoran muy activamente).
Me encantó por como lo has descrito Sergio !!! Un amigo que programa con Python bastante activamente para OO ya me había comentado que era un gusto manipular información en documentos .odt, pero la verdad como apenas empiezo no sabía bien los porques de eso. Creo que tu me has ya dado una idea más exacta del porque. Gracias !!!

#6
Posted 05 June 2012 - 02:27 AM
for i:=0 to Word.ActiveDocument.StoryRanges.Count do begin Texto:=Word.ActiveDocument.StoryRanges.Item(i).Find; Texto.ClearFormatting; Texto.Text:='Certificado'; Texto.Replacement.ClearFormatting; Texto.Replacement.Text:= Texto.Text + DataModule1.IBQueryParticipantesCursoxCliente.FieldByName('EMP_NOMBRE').AsString; end;
Pero siempre me salta el error : "Ele elemento del conjunto solicitado no existe"
Ya he comprobado que a pesar que el Count me dice que tiene 6 elementos, sólo encuentra algo en los elementos 1 y 5, los otros me sale el mismo.
Alguien tiene idea de como puedo hacer el código en Delphi 7 ?
#7
Posted 05 June 2012 - 03:09 AM
#8
Posted 05 June 2012 - 05:05 AM
Te has ofuscado con lo dificil de buscar y reemplazar que has caido en lo más sencillo: si el for empieza por 0, termina por count-1 !!!
Ya llevas razón el que código que subí ya es uno de andar me rompiendo la cabeza probando. Ya o hice empezando de 1 y el mismo.
De hecho por los cambios que hace ya salta en el primer valor que no encuentra.
El Forecha no utiliza un índice, sencillamente va cambiando para el siguiente Range, pero como Delphi 7 (el que utilizo) no sporta ForEach, pues fue como me lo ingenié para intentar hacerlo.
Por lo visto no funciona para recorrer todo el documento ir saltando por los items con un índice.
Tu cuando buscas por un estrucutra de los docs, como los haces ?
Agradezco cualquier ayuda.
Abrazos,
Felipe
#9
Posted 06 June 2012 - 05:31 AM
Por lo que parece, lo correcto sería pedirle al document el storyrange de todos los cuadros de textos (parece que todos forman un solo story) así:
Range:= ActiveDocument.StoryRanges.Items( wdTextFrameStory );
Donde la constante la puedes "adivinar" con una macro de word que te la muestra en un menasaje o algo así (o quizas en word.pas, yo nunca he usado estas unidades).
Y luego tendrías que ir iterando por todos los rangos (cuadros de texto) de esta colección, usand lo del next:
Range:= ActiveDocument.StoryRanges.Items( wdTextFrameStory ); //Haces el find en este primer cuadro de texto While Assigned(Range.NextStoryRange) do begin Range:= Range.NextStoryRange; //Repites el find en este cuadro de texto end;
Todo esto esta sin comproblarlo, te toca hacer pruebas y ver si funciona o no, pero algo es algo!
Eso si, cuando te funciuone pon el código que a mi por lo menos me guastaría hacerle un copy-paste!
#10
Posted 06 June 2012 - 05:42 AM
Abrazos amigo.
#11
Posted 06 June 2012 - 08:30 AM
Tuve que cambiar 2 cosillas pero me va perfecto, eso que el dichosos documento otra cosa no tiene, pero campos de texto y imágenes... pues a patadas.
Ahí va el código, espero que te sea útil como me ha sido y que todos amigos del Foro que siempre me ayudan se sienta a gusto de hacer vuestros copy/paste
//Contenedor es una variable de tipo Range //Word es como he llamado el objeto TWordApplication que tienes que insertar en tu formulario para trabajar con Word //Pillar el primero Range que sea del tipo TextFrame del Story del documento Contenedor:= Word.ActiveDocument.StoryRanges.Item(wdTextFrameStory); //Código para buscar dentro de ese Range el texto buscado, sustituirlo por el que texto deseado y guardar el documento Texto:=Contenedor.Find; Texto.ClearFormatting; Texto.Text:='D. /Dña.:'; Texto.Replacement.ClearFormatting; Texto.Replacement.Text:= Texto.Text + DataModule1.IBQueryParticipantesCursoxCliente.FieldByName('EMP_NOMBRE').AsString; orden:=1; Texto.Execute(EmptyParam, EmptyParam, EmptyParam, EmptyParam, EmptyParam, EmptyParam, EmptyParam, EmptyParam, EmptyParam, EmptyParam, orden, EmptyParam, EmptyParam, EmptyParam, EmptyParam); Word.ActiveDocument.Save; //Bucle que chequea si el proximo Range está Asignado o no While Assigned(Prueba.NextStoryRange) do begin //Saltar para el siguiente Range volver a hacer la búsqueda en el mismo y guardar 3el documento Contenedor:= Contenedor.NextStoryRange; Texto:=Contenedor.Find; Texto.ClearFormatting; Texto.Text:='D. /Dña.:'; Texto.Replacement.ClearFormatting; Texto.Replacement.Text:= Texto.Text + DataModule1.IBQueryParticipantesCursoxCliente.FieldByName('EMP_NOMBRE').AsString; orden:=1; Texto.Execute(EmptyParam, EmptyParam, EmptyParam, EmptyParam, EmptyParam, EmptyParam, EmptyParam, EmptyParam, EmptyParam, EmptyParam, orden, EmptyParam, EmptyParam, EmptyParam, EmptyParam); Word.ActiveDocument.Save; end; //Cerrar y guardar el documento Word.Quit; Word.Disconnect;
#12
Posted 06 June 2012 - 11:38 AM
De todas formas, al menos echo en falta la declaración de la constante wdTextFrameStory, quizas la toma de la unidad de definiciones de word, excel, etc., ya te digo que nnuca la he usado ¿sabes el valor como integer (me ahorro buscarlo yo, je je)?
#13
Posted 07 June 2012 - 01:15 AM
Sobre tu otra pregunta hice la prueba
Contenedor:= Word.ActiveDocument.StoryRanges.Item(wdTextFrameStory); ShowMessage(IntToStr(wdTextFrameStory));
Para el caso de ese documento en el cual trabajo me salió 5.
Pero por lo que entendí eso va a variar según el documento, pq creo que ese seria el quinto Range del Story del documento Activo.
#14
Posted 07 June 2012 - 01:19 AM
Aprovecho el post y pregunto:
Sabes como puedo buscar un texto, ir al final de esa posición y insertar un texto (no cambiarlo) ?
Comento porque con el código que tengo ahora lo logro hacer, pero el tema es que el testo que quiero insertar tiene un formato de fuente, negrita, etc. distinto al que tiene. Con el Replace el me pilla toda la formatación.
Tienes idea de como hacerlo ?
#15
Posted 07 June 2012 - 01:51 AM
Hola Sergio. A mi tb se me hizo raro, de hecho nunca me lo imaginaria que irían por ahí los tiros con ese variable. Creo que lo pilla de las definiciones de la api de word.
Sobre tu otra pregunta hice la prueba
delphi
Contenedor:= Word.ActiveDocument.StoryRanges.Item(wdTextFrameStory); ShowMessage(IntToStr(wdTextFrameStory));
Para el caso de ese documento en el cual trabajo me salió 5.
Pero por lo que entendí eso va a variar según el documento, pq creo que ese seria el quinto Range del Story del documento Activo.
Es una constante, por eso al principio no funcionaban las cosas: Tienes varias "zonas", el cuerpo, el pie, la cabeza, los frames de texto, cada una de estas "zonas" tiene su constante, y usando la constante localizas el primer cuadro de texto de tu documento, o el primer pie de pagina, y luego vas saltando a los adicionales con el findnext.
Asi que la lista de storys es de una longitud máxima pequeña, 6 u 8, pero de cada story cuelga una lista de zonas de esa familia.
#16
Posted 07 June 2012 - 02:19 AM
Sergio,
Aprovecho el post y pregunto:
Sabes como puedo buscar un texto, ir al final de esa posición y insertar un texto (no cambiarlo) ?
Comento porque con el código que tengo ahora lo logro hacer, pero el tema es que el testo que quiero insertar tiene un formato de fuente, negrita, etc. distinto al que tiene. Con el Replace el me pilla toda la formatación.
Tienes idea de como hacerlo ?
Yo, para cambiar texto, uso solamente una línea de código:
Word.ActiveDocument.Content.Find.Execute(SearchTxt, true, false, false, false, false,,,, ReplaceTxt, SearchAll);
Y con esa línea no le paso nada de formateo, el texto se cambia tal cual este ese párrafo (negrita o lo que sea), así que si quieres escribir " el que lo lea" despues de encontrar la palabra "tonto", yo lo suelo hacer esto:
1) Cambio 'tonto' por '<@@> el que lo lea'
2) Cambio '<@@>' por 'tonto'
Lo hago en dos fases por evitar posibles bucles (tonto -> tonto el que lo lea -> tonto el que lo lea el que lo lea -> etc) aunque supongo que word es más listo que eso... pero yo siempre uso cambios que no creen bucles!
Aqui el truco es que "escribir una cosa despues de encontrar la palabra 'tonto'" es igual que "cambiar 'tonto' por 'tonto el que lo lea'".
#17
Posted 07 June 2012 - 02:36 AM
Yo, para cambiar texto, uso solamente una línea de código:
delphi
Word.ActiveDocument.Content.Find.Execute(SearchTxt, true, false, false, false, false,,,, ReplaceTxt, SearchAll);
Y con esa línea no le paso nada de formateo, el texto se cambia tal cual este ese párrafo (negrita o lo que sea), así que si quieres escribir " el que lo lea" despues de encontrar la palabra "tonto", yo lo suelo hacer esto:
1) Cambio 'tonto' por '<@@> el que lo lea'
2) Cambio '<@@>' por 'tonto'
Lo hago en dos fases por evitar posibles bucles (tonto -> tonto el que lo lea -> tonto el que lo lea el que lo lea -> etc) aunque supongo que word es más listo que eso... pero yo siempre uso cambios que no creen bucles!
Aqui el truco es que "escribir una cosa despues de encontrar la palabra 'tonto'" es igual que "cambiar 'tonto' por 'tonto el que lo lea'".
Vale eso el mio tb lo hace (aun que voy probar con la tuya, me pareció más elegante), el tema es no quiero mantener la formatación, sencillamente porque el anterior tiene negrita y el texto a ser insertado no tiene negrita.
O sea quiero meter texto con la formatación que yo prefiera.
Cuando descubrí como hacer las búsqueda sin perder formato del documento así me ha salido, no topé como insertar después de la posición donde el encuentra el texto buscado, que es el ideal y así ya miré algún ejemplo de como pasar el formato deseado para el texto. Pero como ponerlo en esa posición y hacer la inserción no he sido capaz.
#18
Posted 07 June 2012 - 06:48 AM
Hace ya años que desterré word y excel de mis pc, incluidos los del trabajo, así que en esta ocasión no te puedo ayudar mucho más!
#19
Posted 08 June 2012 - 12:54 AM
Aparte de que insertar después de algo es como buscar y sustituir con el truco que te comenté, si quieres saber como insertar texto con formato, yo siempre empiezo intentando grabar en word una macro que haga exactamente eso, y luego la estudio a ver como lo grabo word... no siempre ayuda, pero muchas veces te dá la clave.
Hace ya años que desterré word y excel de mis pc, incluidos los del trabajo, así que en esta ocasión no te puedo ayudar mucho más!
Ya me has ayudado muchísimo amigo !!! Grandes abrazos !!!