portapapeles pegar definicion datos copiar vba ms-word word-vba

vba - pegar - portapapeles windows



copiar contenido de documentos de Word sin usar el portapapeles(VBA) (5)

Me preguntaba cómo evitar el uso del portapapeles de Windows, cuando desea "replicar" varias secciones de un documento de Word (usando VBA en macros)

¿Por qué evitar? Porque estamos usando Word en un servidor, en un entorno multiusuario (sé que oficialmente está mal visto)

De lo contrario, esto se lograría fácilmente con los métodos Selection.Copy y Selection.Paste.

Gracias.


Use la propiedad Text del objeto Selection para poner los datos en una variable de cadena en lugar de en el portapapeles:

Dim strTemp como cadena

strTemp = Selection.Text

A continuación, puede insertar el texto almacenado en la variable en otro lugar según sea necesario.


Finalmente resolví copiar palabra por palabra. FormattedText pareció funcionar bastante bien, hasta la última palabra (algunos caracteres especiales (evidentemente)), donde de repente la celda que acabo de llenar con contenido copiado quedaría en blanco. Cuando aumentaba el número de celdas, aparecían otros errores de tiempo de ejecución, como por ejemplo, Tu tabla se corrompió y otras ambiguas. De alguna manera, la celda fuente de la que estaba copiando siempre parecía tener estos caracteres peculiares al final con los códigos ASCII 13 y 7. Sé lo que significa 13, pero 7? De todos modos, decidí copiar todo aparte de este último personaje con el código 7. Parece que funciona bien. Tanto el formato como los campos se copian también. En cualquier caso, toda la historia me demostró una vez más que la programación en VBA es principalmente de ensayo y error. Nunca está seguro de cuándo se puede romper algo ... a menos que me pierda la actualización de algunos conceptos cruciales.

Aquí están los pedazos del código que utilicé. La idea es que primero tenemos un documento con una sola tabla de células 1x1, con un contenido de texto enriquecido. En la primera parte del código (dentro de una macro) multiplico las celdas:

(TEN EN CUENTA que puse // delante de cada comentario de VB tipo apóstrofo para que el comentario se coloreara correctamente)

Dim cur_width As Integer, i As Integer, max_cells As Integer, cur_row As Integer Dim origin_width As Integer If ActiveDocument.Tables.Count = 1 _ And ActiveDocument.Tables(1).Rows.Count = 1 _ And ActiveDocument.Tables(1).Columns.Count = 1 _ Then max_cells = 7 //'' how many times we are going to "clone" the original content i = 2 //'' current cell count - starting from 2 since the cell with the original content is cell number 1 cur_width = -1 //'' current width cur_row = 1 //'' current row count origin_width = ActiveDocument.Tables(1).Rows(1).Cells(1).Width //'' loop for each row While i <= max_cells //'' adjust current width If cur_row = 1 Then cur_width = origin_width Else cur_width = 0 End If //'' loop for each cell - as long as we have space, add cells horizontally While i <= max_cells And cur_width + origin_width < ActiveDocument.PageSetup.PageWidth Dim col As Integer //'' / returns floor() of the result col = i / ActiveDocument.Tables(1).Rows.Count // ''add cell, if it is not already created (which happens when we add rows) If ActiveDocument.Tables(1).Rows(cur_row).Cells.Count < col Then ActiveDocument.Tables(1).Rows(cur_row).Cells.Add End If // ''adjust new cell width (probably unnecessary With ActiveDocument.Tables(1).Rows(cur_row).Cells(col) .Width = origin_width End With // ''keep track of the current width cur_width = cur_width + origin_width i = i + 1 Wend //'' when we don''t have any horizontal space left, add row If i <= max_cells Then ActiveDocument.Tables(1).Rows.Add cur_row = cur_row + 1 End If Wend End If

En la segunda parte de la macro llené cada celda vacía con el contenido de la primera celda:

//'' duplicate the contents of the first cell to other cells Dim r As Row Dim c As Cell Dim b As Boolean Dim w As Range Dim rn As Range b = False i = 1 For Each r In ActiveDocument.Tables(1).Rows For Each c In r.Cells If i <= max_cells Then // '' don''t copy first cell to itself If b = True Then //'' copy everything word by word For Each w In ActiveDocument.Tables(1).Rows(1).Cells(1).Range.Words //'' get the last bit of formatted text in the destination cell, as range //'' do it first by getting the whole range of the cell, then collapsing it //'' so that it is now the very end of the cell, and moving it one character //'' before (because collapsing moves the range actually beyond the last character of the range) Set rn = c.Range rn.Collapse Direction:=wdCollapseEnd rn.MoveEnd Unit:=wdCharacter, Count:=-1 //'' somehow the last word of the contents of the cell is always Chr(13) & Chr(7) //'' and especially Chr(7) causes some very strange and murky problems //'' I end up avoiding them by not copying the last character, and by setting as a rule //'' that the contents of the first cell should always contain an empty line in the end If c.Range.Words.Count <> ActiveDocument.Tables(1).Rows(1).Cells(1).Range.Words.Count Then rn.FormattedText = w Else //''MsgBox "The strange text is: " & w.Text //''the two byte values of this text (which obviously contains special characters with special //''meaning to Word can be found (and watched) with //''AscB(Mid(w.Text, 1, 1)) and AscB(Mid(w.Text, 2, 1)) w.MoveEnd Unit:=WdUnits.wdCharacter, Count:=-1 rn.FormattedText = w End If Next w End If b = True End If i = i + 1 Next c Next r

Aquí están las imágenes del documento de Word en cuestión. La primera imagen es antes de ejecutar la macro, la segunda es entre el primer fragmento de código y la última, mientras que la tercera imagen es el documento resultante.

Imagen 1 Imagen 2 Imagen 3

Eso es.


Esto no siempre funciona, con campos de texto, diagramas, por ejemplo, o si necesita copiarlo a otro documento, pero es bueno para copiar texto con formato simple dentro de un documento.

''First select something, then do Word.WordBasic.CopyText ''Then move somewhere Word.WordBasic.OK;

Para copiar el documento completo a un documento nuevo, use esto:

Word.Application.Documents.Add Word.ActiveDocument.FullName


Me encontré con un problema similar. Quería copiar una tabla de un documento de Word a otro usando Powershell sin usar el portapapeles. Dado que un usuario que utiliza la computadora mientras se ejecutaba la secuencia de comandos podía romper la secuencia de comandos mediante el uso del portapapeles. La solución que se me ocurrió fue:

  1. Abra el documento de origen y coloque un marcador que cubra el rango de lo que quería (en mi caso, una sola tabla).
  2. Guarde el documento fuente con su marcador en otra ubicación (para evitar cambiar el documento fuente).
  3. Abrí el documento de destino y creé un objeto de rango para el lugar donde quería colocar la tabla.
  4. range.InsertFile con el primer parámetro del archivo de origen con mi marcador y el segundo parámetro de mi nombre de marcador. Esta operación única extrajo la tabla completa más el formato de la fuente directamente en el documento de destino.

Luego agregué el código en función de dónde se realizaba la inserción y cuánto tiempo más era la historia para seleccionar la tabla insertada para permitir más operaciones en ella.

Probé muchos otros métodos para mover la mesa y este fue de lejos el mejor. Lo siento, no puedo proporcionar el código VBA para esta solución.


En Office 2007+ VSTO, puede exportar el bloque con Range.ExportFragment y luego ir a su nuevo documento e importarlo con Range.ImportFragment . No lo he usado en producción, pero experimenté con él y parece funcionar bien.

Una advertencia, recibí errores al intentar exportar como .docx, pero RTF parecía funcionar bien.

Ambos métodos existen también en VBA, pero solo probé los métodos de VSTO.