Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

(vba) Recorrer celdas copiadas en el clipboard

329 views
Skip to first unread message

jose

unread,
Jun 29, 2009, 3:13:00 PM6/29/09
to

Buenas,
Necesito una macro que recorra las celdas que copié anteriormente de manera
manual. Esto significa:

a) Escribo "hola" en A1 y "mundo" en A2.
b) Selecciono, manualmente (sin macros), A1 y A2, Edición y Copiar.

Ahora bien, tengo en el clipboard los valores de A1 y A2.

Quiero ejecutar ahora una macro que tome del clipboard el rango A1:A2, los
recorra para obtener del portapapeles los valores "Hola" y "Mundo".

Gracias

H�ctor Miguel

unread,
Jun 29, 2009, 3:26:43 PM6/29/09
to

hola, jose !

> Necesito una macro que recorra las celdas que copie anteriormente de manera manual...:


> a) Escribo "hola" en A1 y "mundo" en A2.

> b) Selecciono, manualmente (sin macros), A1 y A2, Edicion y Copiar.


> Ahora bien, tengo en el clipboard los valores de A1 y A2.
> Quiero ejecutar ahora una macro que tome del clipboard el rango A1:A2

> los recorra para obtener del portapapeles los valores "Hola" y "Mundo".

para trabajar con el portapapeles (de windows) desde vba, necesitaras mas de dos lineas de codigo
(dependiendo de lo que necesites hacer con los datos en/a dicho clipboard)

prueba consultando la informacion de la siguiente pagina:
Using The Clipboard In VBA
http://www.cpearson.com/Excel/clipboard.aspx

saludos,
hector.


jose

unread,
Jun 29, 2009, 3:57:01 PM6/29/09
to

Lo ví anteriormente pero tiene dos temas:

1) Storing Multiple Items In The Clipboard no me funcionó, me dice que
almacena los valores pero luego me da "Format does not exist on clipboard."
(por B en false). Si intento Pegar común, excel me dice "microsoft office
excel cannot paste the data." (uso excel 2003)

2) Suponiendo que funcione el punto 1). En el ejemplo, se copia desde una
macro, y le setea nombre "FormatId". Yo necesito el copy común del usuario,
por lo que no se el nombre con el que Excel copia al portapapeles.

gracias.

H�ctor Miguel

unread,
Jun 29, 2009, 4:21:14 PM6/29/09
to

hola, jose !

> Lo vi anteriormente pero tiene dos temas:
> 1) Storing Multiple Items In The Clipboard no me funciono
> me dice que almacena los valores pero luego me da "Format does not exist on clipboard" (por B en false).
> Si intento Pegar comun, excel me dice "microsoft office excel cannot paste the data." (uso excel 2003)


> 2) Suponiendo que funcione el punto 1). En el ejemplo, se copia desde una macro, y le setea nombre "FormatId".

> Yo necesito el copy comun del usuario, por lo que no se el nombre con el que Excel copia al portapapeles...

1) de los primeros comentarios en la pagina sugerida, habras notado el siguiente:
"VBA does not support the data type required for other, non-text, values on the clipboard"

2) retomando el comentario del mensaje anterior...
"... necesitaras mas de dos lineas de codigo"


"(dependiendo de lo que necesites hacer con los datos en/a dicho clipboard)"

supongo que tendrias que buscar adaptar otro tipo de funciones (no nativas de VBA) como p.e.:
-> EnumClipboardFormats: Identify Clipboard Data Available
http://vbnet.mvps.org/code/system/cb_enumclipboardformats.htm

3) serviria tambien si comentas algo menos... "generico", p.e.:
-> cual es la necesidad de "consultar" al portpapeles si tienes disponibe "el origen" de los datos (?)
-> algun otro detalle que tu conoces pero que no se puede "adivinar" desde este lado (del mensaje) ?

saludos,
hector.


jose

unread,
Jun 29, 2009, 4:41:01 PM6/29/09
to

Hola Héctor, mira, el "origen" no lo puedo saber en realidad, porque el Copy
puede ser de un excel que cerré. Pasos:

1) abro un libro.
2) Copio A1:A2
3) Cierro libro.

luego quiero pegar con una macro en otro libro A1:A2. El origen lo perdí
porque cerré el libro.

Mucho de lo que quiero hacer tiene relación con otro post que realicé:

"Pegar en celdas con merge". Tengo un origen de una planilla exportada a
excel de un sistema, en tabla plana, y necesito pegarla en una planilla con
celdas con merge. Pero se tiene que pasar a través de copy/paste, no se puede
utilizar fórmulas (antes ponía un =[Book2]Sheet1!A1 en las celdas con merge,
luego copy y paste con value, pero ya no sirve), ni copiar columna por
columna, etc.

por ahí con tener "Pegar en celdas con merge" me da una idea.

Seguiré investigando este tema, gracias.

"Héctor Miguel" wrote:

-----------------------------------------------------------------------------
Our Peering Groups change
Visit : http://spacesst.com/peerin

H�ctor Miguel

unread,
Jun 29, 2009, 4:56:55 PM6/29/09
to
hola, jose !

> ... el "origen" no lo puedo saber en realidad, porque el Copy puede ser de un excel que cerre. Pasos:


> 1) abro un libro.
> 2) Copio A1:A2
> 3) Cierro libro.

> luego quiero pegar con una macro en otro libro A1:A2. El origen lo perdi porque cerre el libro.

=> hasta aqui, puedes reproducir el siguiente ejemplo (con base exclusivamente en los detalles de esta consulta)

1) abres un libro
2) copias A1:A2
3) cierras el libro
4) obtienes los datos desde el clipboard (no importa si el libro "de origen" ya se ha cerrado) con una macro +/- asi:

Sub Pegar_cliboard()
Range("a1").Select
ActiveSheet.PasteSpecial
End Sub

> Mucho de lo que quiero hacer tiene relacion con otro post que realice: "Pegar en celdas con merge".


> Tengo un origen de una planilla exportada a excel de un sistema, en tabla plana, y necesito pegarla en una planilla con celdas con merge.

> Pero se tiene que pasar a traves de copy/paste, no se puede utilizar formulas
> (antes ponia un =[Book2]Sheet1!A1 en las celdas con merge, luego copy y paste con value, pero ya no sirve)


> ni copiar columna por columna, etc.

=> con el tema de las celdas "combinadas"...
(prefiero no meterme hasta tener al detalle todo lo que se requiere hacer con ellas) :))

saludos,
hector.

-----------------------------------------------------------------------------
Less Spam Better enjoyable experience
Visit : news://spacesst.com

jose

unread,
Jun 30, 2009, 1:44:00 PM6/30/09
to

solución:

Option Explicit

Private DataObj As New MSForms.DataObject

Sub CopyForMerge()
Set DataObj = New MSForms.DataObject

Dim range As range
Set range = Selection.range(Selection.address)

Dim iniRow As Integer
Dim iniCol As Integer
Dim endRow As Integer
Dim endCol As Integer

iniRow = Split(Replace(Replace(Replace(Replace(range.address(0, 0,
xlR1C1), "R", ""), "C", ""), ":", ""), "[", ""), "]")(0)
iniCol = Split(Replace(Replace(Replace(Replace(range.address(0, 0,
xlR1C1), "R", ""), "C", ""), ":", ""), "[", ""), "]")(1) - 1
endRow = Split(Replace(Replace(Replace(Replace(range.address(0, 0,
xlR1C1), "R", ""), "C", ""), ":", ""), "[", ""), "]")(2)
endCol = Split(Replace(Replace(Replace(Replace(range.address(0, 0,
xlR1C1), "R", ""), "C", ""), ":", ""), "[", ""), "]")(3) - 1

Dim i As Integer
Dim j As Integer

For i = iniRow To endRow
For j = iniCol To endCol
DataObj.SetText Cells(i, j).text, "JLF|" & i - iniRow & "|" & j
- iniCol
Next j
Next i
End Sub

Sub PasteForMerge()
Dim i As Integer
Dim j As Integer
Dim x As Integer
Dim y As Integer
x = 0
y = 0

Dim exist As Boolean

For i = Selection.row To Selection.row + 10
For j = Selection.column To Selection.column + 10
exist = DataObj.GetFormat("JLF|" & x & "|" & y)
If exist = True Then
Do While IsMergedHide(j, i)
j = j + 1
Loop
Cells(i, j).Value = DataObj.GetText("JLF|" & x & "|" & y)
Debug.Print DataObj.GetText("JLF|" & x & "|" & y)
Else
Exit For
End If
y = y + 1
Next j
x = x + 1
y = 0
exist = DataObj.GetFormat("JLF|" & x & "|" & y)
If exist = False Then
Exit For
End If
Next i
End Sub

Function IsMergedHide(column As Integer, row As Integer)
If Cells(row, column).MergeCells Then
Dim rowIni As Integer
Dim columnIni As Integer
'Dim rowFin As Integer
'Dim columnFin As Integer

Dim address As String
address = Replace(Replace(Replace(Cells(row,
column).MergeArea.address(False, False, xlR1C1), "R", ""), "C", ""), "[", "")
rowIni = Split(Split(address, ":")(0), "]")(0) + 1
columnIni = Split(Split(address, ":")(0), "]")(1) + 1
'rowFin = Split(Split(address, ":")(1), "]")(0) + 1
'columnFin = Split(Split(address, ":")(1), "]")(1) + 1

If column = columnIni And row = rowIni Then
IsMergedHide = False
Else
IsMergedHide = True
End If
Else
IsMergedHide = False
End If
End Function


H�ctor Miguel

unread,
Jun 30, 2009, 3:49:21 PM6/30/09
to

hola, jose !

> solucion:

interesente... podrias comentar donde conseguiste este codigo (para poder analizar "el contexto")
si olvidar que la "pega" sigue estando si nos sujetamos a tu comentario (en tu segundo menssje) de que...
"Yo necesito el copy comun del usuario." (???)

saludos,
hector.

__ el codigo expuest __

H�ctor Miguel

unread,
Jul 1, 2009, 3:48:52 AM7/1/09
to

hola (de nuevo), jose !

>> solucion:
>
> interesente... podrias comentar donde conseguiste este codigo (para poder analizar "el contexto") ?


> si olvidar que la "pega" sigue estando si nos sujetamos a tu comentario (en tu segundo menssje) de que...
> "Yo necesito el copy comun del usuario." (???)

haciendo pruebas "cortas" con los inicios del codigo que expones, podrias adelgazar la obtencion de las variables si cambias:

de esto:
Dim myRange As Range, iniRow As Integer, iniCol As Integer, endRow As Integer, endCol As Integer
Set myRange = Selection.Range(Selection.Address)
iniRow = Split(Replace(Replace(Replace(Replace(myRange.Address(0, 0, xlR1C1), "R", ""), "C", ""), ":", ""), "[", ""), "]")(0)
iniCol = Split(Replace(Replace(Replace(Replace(myRange.Address(0, 0, xlR1C1), "R", ""), "C", ""), ":", ""), "[", ""), "]")(1) - 1
endRow = Split(Replace(Replace(Replace(Replace(myRange.Address(0, 0, xlR1C1), "R", ""), "C", ""), ":", ""), "[", ""), "]")(2)
endCol = Split(Replace(Replace(Replace(Replace(myRange.Address(0, 0, xlR1C1), "R", ""), "C", ""), ":", ""), "[", ""), "]")(3) - 1

a esto:
Dim iniRow As Integer, iniCol As Integer, endRow As Integer, endCol As Integer
With Selection
iniRow = .Row
iniCol = .Column
endRow = .Rows.Count + .Row - 1
endCol = .Columns.Count + .Column - 1
End With

aparte de que trae algunas inconsistencias y no funciona cuando la celda inicial esta en la fila1/columna1 (entre otros)

pero como te comentaba: haria falta conocer "el contexto" del tema donde encontraste este codigo (?)

saludos,
hector.


jose

unread,
Jul 1, 2009, 9:34:01 AM7/1/09
to

Contexto: http://tinyurl.com/mexxes

Hola Héctor, te comento que yo programé el código. Le hice algunos cambios
más:

a)

Private Sub Workbook_Open()
Application.OnKey "^c", "CopyForMerge"
Application.OnKey "^v", "PasteForMerge"
End Sub

b) Al CopyForMerge le agregué un Selection.Copy. Se ve que el copy de excel
y el copy del DataObject corren por dos caminos diferentes.

c) al PasteForMerge le agregué un condicional:

If Selection.MergeCells Then
hace el paste por el código que envié.
si no es es merge hace el paste común:

ActiveSheet.Paste

d) Mejoré la detección de la detección de celda inicio/fin del rango:

iniRow = Selection.EntireRow.row
iniCol = Selection.EntireColumn.column
endRow = iniRow + Selection.rows.Count - 1
endCol = iniCol + Selection.columns.Count - 1


De esa forma el usuario hace "copy/paste" y usa mi código, ya que no pude
hacer lo del "Yo necesito el copy comun del usuario."


http://tinyurl.com/mexxes

jose

unread,
Jul 1, 2009, 9:37:01 AM7/1/09
to

gracias!! no lo había visto...y lo había solucionado con.

iniRow = Selection.EntireRow.row
iniCol = Selection.EntireColumn.column
endRow = iniRow + Selection.rows.Count - 1
endCol = iniCol + Selection.columns.Count - 1

0 new messages