Tablas insertadas con Word

Soy usuario de Visual Basic 6 desde hace un año. Tengo problemas a la hora de entender el mecanismo de OLE Automatización entre otras cosas porque no lo tengo documentado a pesar de tener varios libros de VB 6, uno muy bueno de 1200 págs. Pero donde no viene nada del objeto Word.
Estoy haciendo un programa y necesito incrustar datos y tablas en plantillas. En un principio lo hice con archivos Word salvados como .RTF y donde sustituía palabras. Quedaba muy bien porque además podía abrir el archivo en el programa y quedaba muy bien, sino fuese por los arreglos que tuve que hacer debido a que el formato .RTF no quedaba del todo bien como yo quería y me veía "negro" para apañarlo. No obstante, el resultado era muy bueno porque al cargar el archivo .RTF de la plantilla y copiarse mediante FileCopy, daba una rapidez que no la ofrece un .DOC.
Ahora he conseguido varis ejemplos de internet para manejar .DOC para tablas con y sin marcadores.
Con marcador, sé insertar una tabla, pero he intentado crear una rutina con un procedimiento y al repetir con otra tabla se me incrusta en los campos que ya tengo a pesar de cambiar de marcador. Por lo visto, el fallo consiste en que abría que añadir una sentencia en la que se pusiera "pasar al siguiente marcador", pero te vuelvo a comentar que no he conseguido una documentación fidedigna de dicho objeto por lo que estoy perdido.
Sin marcador, el ejemplo abre un documento nuevo e inserta una tabla, por cierto con más rapidez que con el toro método, pero necesitaría que el archivo estuviese ya generado y yo cambiar la plantilla.
En resumen:
1) Necesito una mayor descripción del objeto Word que no he encontrado.
2) Conocer como incrustar varias tablas en un sólo .DOC con marcadores y sin marcadores.

1 Respuesta

Respuesta
1
No utilizo el control ole, trabajo con el objeto createobject y desde ahí en forma directa creo el documento de word o abro la plantilla y la utilizo de acuerdo a mis necesidades, sugiero veas las siguientes aplicaciones de word:
Gracias, David Enciso (siento la confusión con el apellido).
Bien, resulta que logré mis propósitos y he conseguido descubrir por mis propios métodos porqué fallaba.
Contéstame brevemente qué posibilidades tiene el objeto createobject, qué referencia hay que tomar en VB, y que manipulación se puede lograr y te finalizo la respuesta
Option Explicit.
Acompaño un listado de un formulario con el uso de incrustación de tablas y marcadores por si alguien lee esta respuesta.
Saludos.
Dim RutaBaseDatos As String
Dim RutaDocumento As String
Dim NombreTabla As String
Dim NúmeroTabla As Integer
Dim NombreMarcador As String
Dim NombresCampos As Variant
Dim Marcador As String
Dim Texto As String
Dim o_Word As Word.Application
Dim Documento As Word.Document
Private Sub Command1_Click()
' Establece la referencia al Word
Set o_Word = New Word.Application
' Pone el Word no visible
o_Word.Visible = False
' Rutas del documento y de la Base de Datos
RutaBaseDatos = "C:\Archivos de programa\Termical\Proyectos\new\BASE DATOS\Cerramientos.MDB"
RutaDocumento = "C:\Documents and Settings\All Users\Documentos\ETSII UNED\" & _
"PROYECTO FIN DE CARRERA\Programa PFC\ArchivoWord2.doc"
'Abrimos el documento "ArchivoWord2.doc" con Open (mejor aquí que en los procedimientos de copia)
Set Documento = o_Word.Application.Documents.Open(RutaDocumento)
' Inserción del texto nº 1
Marcador = "Texto1"
Texto = "Tablas de Cerramientos y Huecos"
Call CopiarDatosEnWord(RutaDocumento, Marcador, Texto)
' Inserción del texto nº 2
Marcador = "Texto2"
Texto = "Estas son las tablas:"
Call CopiarDatosEnWord(RutaDocumento, Marcador, Texto)
'Inserción de la 1ª tabla
NombreTabla = "Muro"
NombreMarcador = "Tabla1"
NombresCampos = "Material,Espesor,Resistencia"
NúmeroTabla = 1
Call CopiarTablaEnWord(RutaBaseDatos, RutaDocumento, NombreTabla, NúmeroTabla, NombreMarcador, NombresCampos)
' Inserción de la 2ª tabla
NombreTabla = "Ventana_1"
NombreMarcador = "Tabla2"
NombresCampos = "Nombre, ClaseTipo,Tipologia,TipoMarco"
NúmeroTabla = 2
Call CopiarTablaEnWord(RutaBaseDatos, RutaDocumento, NombreTabla, NúmeroTabla, NombreMarcador, NombresCampos)
' Guardamos y cerramos el documento
o_Word.Application.Documents.Save
o_Word.Application.Documents.Close
' Cerramos Word
o_Word.Quit
'Descargamos los objetos
Set o_Word = Nothing
Set Documento = Nothing
End Sub
' Rutina que copia una tabla de un DataGrid a un documento de Word en la posición definida para un marcador
' Los argumentos son:
' RutaBaseDatos : ruta completa donde está la base datos de Access
' Ejemplo: RutaBaseDatos = "C:\Archivos de programa\Termical\Proyectos\new\BASE DATOS\Cerramientos.mdb"
' RutaDocumento : ruta completa donde se encuentra el documento de Word
' Ejemplo: RutaDocumento = "C:\Documents and Settings\All Users\Documentos\ PROYECTO\ArchivoWord2.doc"
' NombreTabla : El nombre de la tabla de la base de datos conectada al DataGrid
' Ejemplo: NombreTabla = "Ventana_1"
' NombreMarcador : Nombre dado al marcador en el archivo de Word.
' Ejemplo: NombreMarcador = "Tabla1"
' NombresCampos : Recibe cualquier número de argumentos que son los campos elegidos para la tabla en el orden deseado.
' Ejemplo: NombresCampos = "Nombre, ClaseTipo, Area, TipoVidrio"
' NOTA: Se pueden definir los nombres de variables de los argumentos porque si no, algunos argumentos serán
' excesivamente largos y dificultarían la lectura del procedimiento
Sub CopiarTablaEnWord(RutaBaseDatos As String, RutaDocumento As String, _
NombreTabla As String, NúmeroTabla As Integer, NombreMarcador As String, ParamArray args() As Variant)
Dim cn As ADODB.Connection
Dim rs As ADODB.Recordset
Dim c As Integer ' columna
Dim f As Long ' fila
Dim dato As Variant ' valor de la celda del datagrid
On Error Resume Next
' Conexión Ado
Set cn = New ADODB.Connection
cn.CursorLocation = adUseClient
cn.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data " & _
"Source=" & RutaBaseDatos & ";Persist Security Info=False"
' Cerrar una conexión si está abierta
If cn.State = adStateOpen Then cn.Close
' Abre la base de datos
Con.Open
Command1.Caption = " Mandar Datagrid a Word "
' Crea un recordset
Set rs = New ADODB.Recordset
' Cerrar un Recordset si está abierto.
If rs.State = adStateOpen Then rs.Close
' Llena el recordset
If NombresCampos = "" Or NombresCampos = 0 Then
rs.Open NombreTabla, cn, adOpenStatic, adLockBatchOptimistic, adCmdTable
Else
rs.Open "Select " & NombresCampos & " From " & NombreTabla, _
cn, adOpenStatic, adLockOptimistic
End If
' Enlaza el DataGrid al recordset
Set DataGrid1.DataSource = rs
'Nos vamos al marcador definido en el documento, _
Para insertar la tabla en ese punto
Selection.GoTo What:=wdGoToBookmark, Name:=NombreMarcador
With Documento
'Agregamos la tabla dentro de Word con las _
Filas y columnas que tenga el datagrid
ActiveDocument.Tables.Add Range:=Selection.Range, _
NumRows:=DataGrid1.ApproxCount + 1, _
NumColumns:=DataGrid1.Columns.Count
'Recorremos el DataGrid para agregar las columnas y filas a nuestra tabla
For c = 0 To DataGrid1.Columns.Count - 1
DataGrid1.Row = 0
ActiveDocument.Tables(NúmeroTabla).Cell(1, c + 1).Range.InsertAfter _
DataGrid1.Columns(c).Caption 'agregar columnas
' Recorre las filas de la columna actual
For f = 0 To DataGrid1.ApproxCount - 1
' Almacena el dato de la celda del datagrid de la columna actual
dato = DataGrid1.Columns(c).CellValue(DataGrid1.GetBookmark(f))
' Agrega el dato a la celda de la tabla
ActiveDocument.Tables(NúmeroTabla).Cell(f + 2, c + 1).Range.InsertAfter dato
Next f
Next c
End With
End Sub
' Rutina para sustituir texto de marcadores en archivos .DOC de Word
Sub CopiarDatosEnWord(RutaDocumento As String, Marcador As String, Texto As String)
On Error Resume Next
Selection.GoTo What:=wdGoToBookmark, Name:=Marcador
Selection.TypeText Text:=Texto
End Sub
Gracias, David Enciso (siento la confusión con el apellido).
Bien, resulta que logré mis propósitos y he conseguido descubrir por mis propios métodos porqué fallaba.
Contéstame brevemente qué posibilidades tiene el objeto createobject, qué referencia hay que tomar en VB, y que manipulación se puede lograr y te finalizo la respuesta
Option Explicit.
Acompaño un listado de un formulario con el uso de incrustación de tablas y marcadores por si alguien lee esta respuesta.
Saludos.
Dim RutaBaseDatos As String
Dim RutaDocumento As String
Dim NombreTabla As String
Dim NúmeroTabla As Integer
Dim NombreMarcador As String
Dim NombresCampos As Variant
Dim Marcador As String
Dim Texto As String
Dim o_Word As Word.Application
Dim Documento As Word.Document
Private Sub Command1_Click()
' Establece la referencia al Word
Set o_Word = New Word.Application
' Pone el Word no visible
o_Word.Visible = True
' Rutas del documento y de la Base de Datos
RutaBaseDatos = "C:\Archivos de programa\Termical\Proyectos\new\BASE DATOS\Cerramientos.MDB"
RutaDocumento = "C:\Documents and Settings\All Users\Documentos\ETSII UNED\" & _
"PROYECTO FIN DE CARRERA\Programa PFC\ArchivoWord2.doc"
'Abrimos el documento "ArchivoWord2.doc" con Open (mejor aquí que en los procedimientos de copia)
Set Documento = o_Word.Application.Documents.Open(RutaDocumento)
' Inserción del texto nº 1
Marcador = "Texto1"
Texto = "Tablas de Cerramientos y Huecos"
Call CopiarDatosEnWord(RutaDocumento, Marcador, Texto)
' Inserción del texto nº 2
Marcador = "Texto2"
Texto = "Estas son las tablas:"
Call CopiarDatosEnWord(RutaDocumento, Marcador, Texto)
'Inserción de la 1ª tabla
NombreTabla = "Muro"
NombreMarcador = "Tabla1"
NombresCampos = "Material,Espesor,Resistencia"
NúmeroTabla = 1
Call CopiarTablaEnWord(RutaBaseDatos, RutaDocumento, NombreTabla, NúmeroTabla, NombreMarcador, NombresCampos)
' Inserción de la 2ª tabla
NombreTabla = "Ventana_1"
NombreMarcador = "Tabla2"
NombresCampos = "Nombre, ClaseTipo,Tipologia,TipoMarco"
NúmeroTabla = 2
Call CopiarTablaEnWord(RutaBaseDatos, RutaDocumento, NombreTabla, NúmeroTabla, NombreMarcador, NombresCampos)
' Guardamos y cerramos el documento
o_Word.Application.Documents.Save
o_Word.Application.Documents.Close
' Cerramos Word
o_Word.Quit
'Descargamos los objetos
Set o_Word = Nothing
Set Documento = Nothing
End Sub
' Rutina que copia una tabla de un DataGrid a un documento de Word en la posición definida para un marcador
' Los argumentos son:
' RutaBaseDatos : ruta completa donde está la base datos de Access
' Ejemplo: RutaBaseDatos = "C:\Archivos de programa\Termical\Proyectos\new\BASE DATOS\Cerramientos.mdb"
' RutaDocumento : ruta completa donde se encuentra el documento de Word
' Ejemplo: RutaDocumento = "C:\Documents and Settings\All Users\Documentos\ PROYECTO\ArchivoWord2.doc"
' NombreTabla : El nombre de la tabla de la base de datos conectada al DataGrid
' Ejemplo: NombreTabla = "Ventana_1"
' NombreMarcador : Nombre dado al marcador en el archivo de Word.
' Ejemplo: NombreMarcador = "Tabla1"
' NombresCampos : Recibe cualquier número de argumentos que son los campos elegidos para la tabla en el orden deseado.
' Ejemplo: NombresCampos = "Nombre, ClaseTipo, Area, TipoVidrio"
' NOTA: Se pueden definir los nombres de variables de los argumentos porque si no, algunos argumentos serán
' excesivamente largos y dificultarían la lectura del procedimiento
Sub CopiarTablaEnWord(RutaBaseDatos As String, RutaDocumento As String, _
NombreTabla As String, NúmeroTabla As Integer, NombreMarcador As String, ParamArray args() As Variant)
Dim cn As ADODB.Connection
Dim rs As ADODB.Recordset
Dim c As Integer ' columna
Dim f As Long ' fila
Dim dato As Variant ' valor de la celda del datagrid
On Error Resume Next
' Conexión Ado
Set cn = New ADODB.Connection
cn.CursorLocation = adUseClient
cn.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data " & _
"Source=" & RutaBaseDatos & ";Persist Security Info=False"
' Cerrar una conexión si está abierta
If cn.State = adStateOpen Then cn.Close
' Abre la base de datos
Con.Open
Command1.Caption = " Mandar Datagrid a Word "
' Crea un recordset
Set rs = New ADODB.Recordset
' Cerrar un Recordset si está abierto.
If rs.State = adStateOpen Then rs.Close
' Llena el recordset
If NombresCampos = "" Or NombresCampos = 0 Then
rs.Open NombreTabla, cn, adOpenStatic, adLockBatchOptimistic, adCmdTable
Else
rs.Open "Select " & NombresCampos & " From " & NombreTabla, _
cn, adOpenStatic, adLockOptimistic
End If
' Enlaza el DataGrid al recordset
Set DataGrid1.DataSource = rs
'Nos vamos al marcador definido en el documento, _
Para insertar la tabla en ese punto
Selection.GoTo What:=wdGoToBookmark, Name:=NombreMarcador
With Documento
'Agregamos la tabla dentro de Word con las _
Filas y columnas que tenga el datagrid
ActiveDocument.Tables.Add Range:=Selection.Range, _
NumRows:=DataGrid1.ApproxCount + 1, _
NumColumns:=DataGrid1.Columns.Count
'Recorremos el DataGrid para agregar las columnas y filas a nuestra tabla
For c = 0 To DataGrid1.Columns.Count - 1
DataGrid1.Row = 0
ActiveDocument.Tables(NúmeroTabla).Cell(1, c + 1).Range.InsertAfter _
DataGrid1.Columns(c).Caption 'agregar columnas
' Recorre las filas de la columna actual
For f = 0 To DataGrid1.ApproxCount - 1
' Almacena el dato de la celda del datagrid de la columna actual
dato = DataGrid1.Columns(c).CellValue(DataGrid1.GetBookmark(f))
' Agrega el dato a la celda de la tabla
ActiveDocument.Tables(NúmeroTabla).Cell(f + 2, c + 1).Range.InsertAfter dato
Next f
Next c
End With
End Sub
' Rutina para sustituir texto de marcadores en archivos .DOC de Word
Sub CopiarDatosEnWord(RutaDocumento As String, Marcador As String, Texto As String)
On Error Resume Next
Selection.GoTo What:=wdGoToBookmark, Name:=Marcador
Selection.TypeText Text:=Texto
End Sub
Lo que tienes es una referencia dentro de tu proyecto a word, cualquier versión, y esto te frena el desarrollo cuando en el equipo donde se instale tu proyecto no tenga la misma versión del office y word utilizados. El createobject te permite trabajar con cualquier versión de word sin saber cual sea. Esto te permite la libertad de instalar tu proyecto en cualquier equipo que por lo menos cuente con office...
Gracias por responder.
Únicamente la última aclaración (no lo he probado)
¿Si cambio las siguientes líneas de código:
1)Dim o_Word As Word.Application
2)Dim Documento As Word.Document
3)Set o_Word = New Word.Application
4)Set Documento = o_Word.Application.Documents.Open(RutaDocumento)
por estas otras:
1)Dim o_Word As Object
2)Dim Documento As Object
3)Set o_Word = CreateObject(Word.Application)
4)Set Documento = CreateObject(Word.Application.Documents.Open(RutaDocumento))
¿Bastaría para que funcionara el programa que puse en cualquier ordenador con cualquier versión de Word?
Me temo que Set Documento no está bien asignado.
Gracias anticipadas por las molestias. Es que no me ha quedado claro lo de CreateObject, no encuentro la documentación ni un ejemplo claro del uso
En esencia sí, sugiero que pruebes y veas como te va con los códigos actualizados, ya que no todo lo que usas funciona y lo tienes que ir adaptando...

Añade tu respuesta

Haz clic para o

Más respuestas relacionadas