Crear una macro que me abra un libro "X" y me copie el contenido de varias hojas distintas, a otro libro y sus respectivas hojas

Tengo un archivo de automatización en Excel y necesito copiar varias hojas de un libro "X", en la misma cantidad de hojas, pero la macro que tengo no me permite hacer eso, cuando la grabo me hace el proceso, pero cuando intento organizarla no me lo permite, ya que al ejecutarla lo que hace es copiarme todo en una misma hoja, a pesar de que tiene una dirección seleccionada, abajo las dos macros.

Macro capturada

Sub Macro3()
' Macro3 Macro
Windows("Plan de Contratación Proyectos 2018 VPE PeI.xlsx").Activate

Sheets("HITOS Plan ajustado").Select
Range("A4:BE391").Select
Selection.Copy
Windows("BBDD Autov2.xlsm").Activate
Sheets("Contratacion").Select
Range("A3").Select
ActiveSheet.Paste
Windows("Plan de Contratación Proyectos 2018 VPE PeI.xlsx").Activate
Sheets("Torn Seg PT hito Ant Cumplido").Select
Range("B28:BX33").Select
Application.CutCopyMode = False
Selection.Copy
Windows("BBDD Autov2.xlsm").Activate
Sheets("PT hito ant cump").Select
Range("B2").Select
ActiveSheet.Paste
Sheets("Menú").Select
Windows("Plan de Contratación Proyectos 2018 VPE PeI.xlsx").Activate
ActiveWorkbook.Save
ActiveWindow.Close
End Sub

Macro modificada

Sub Abre_Libro()
' Ventana para cargar archivo de Hitos, en una hoja predeterminada en el libro
Application.ScreenUpdating = False
Application.DisplayAlerts = False
On Error Resume Next

Dim miarchivo, milibro, a, b, c As String

ruta = ActiveWorkbook.Path
ChDir ruta
miarchivo = Application.GetOpenFilename("Archivos Excel (*.xl*), *.xl*") 'Código para cargar archivo

If VarType(miarchivo) = vbBoolean Then
MsgBox ("Operación cancelada"), vbCritical, "AVISO"
Exit Sub
End If

milibro = ActiveWorkbook.Name

Workbooks.Open Filename:=miarchivo, UpdateLinks:=0 ' Abrir hitos y cargar datos a Hoja de Hitos
FullName = Split(miarchivo, Application.PathSeparator)

a = FullName(UBound(FullName))
Set b = Sheets(ActiveSheet.Name)
Workbooks(milibro).Sheets("HITOS Plan ajustado").Select.UsedRange.Copy
Application.ScreenUpdating = False
Range("A3").Select
Range("A3:BE500").Select
Selection.Copy
Windows("BBDD Autov2.xlsm").Activate
Sheets("Contratacion").Select
Range("A3").Select
ActiveSheet.Paste

'Windows("Plan de Contratación Proyectos 2018 VPE PeI.xlsx").Activate
Workbooks(milibro).Sheets("Torn Seg PT hito Ant Cumplido").Select.UsedRange.Copy
Application.ScreenUpdating = False
Range("B28").Select
Range("B28:BX33").Select
Application.CutCopyMode = False
Selection.Copy
Windows("BBDD Autov2.xlsm").Activate
Sheets("PT hito ant cump").Select
Range("B2").Select
ActiveSheet.Paste
'Windows("Plan de Contratación Proyectos 2018 VPE PeI.xlsx").Activate
Workbooks(milibro).Sheets("Torn Seg PM hito Ant Cumpli").Select.UsedRange.Copy
Application.ScreenUpdating = False
Range("B28").Select
Range("B28:BE33").Select
Application.CutCopyMode = False
Selection.Copy
Windows("BBDD Autov2.xlsm").Activate
Sheets("PM hito ant cump").Select
Range("B2").Select
ActiveSheet.Paste
Application.CutCopyMode = False 'Limpiar el portapapeles
Application.Workbooks.Open(miarchivo).Close 'Cerrar archivo del cual copiamos información
Sheets("Menú").Select

MsgBox "Archivo cargado con éxito", vbInformation, "AVISO"
End Sub

1 Respuesta

Respuesta
1

Hay muchos errores en su código, y muchas instrucciones innecesarias. En Excel usted no necesita seleccionar aquí, y luego seleccionar allá, o activar un libro, y luego activar el otro para hacer cosas.

Primero que todo, está declarando mal las variables, si bien es correcto en VB, en VBA lo está haciendo mal.

Dim miarchivo, milibro, a, b, c As String

Eso es un error. De todas esas variables, la única de tipo String es c. El resto (miarchivo, milibro, a, b) son variables vacías, de tipo 0.

Eso esta llevando a otro código innecesario que es:

If VarType(miarchivo) = vbBoolean Then
MsgBox ("Operación cancelada"), vbCritical, "AVISO"
Exit Sub
End If

La variable miarchivo jamás sera de tipo 11 (boolean). Esa variable siempre está retornando 0. por lo que ese pedazo de código no hace nada.

Otra cosa, no se suele desactivar y activar la actualización de pantalla tantas veces. (Application. Screenuptading) con hacerlo una sola vez basta.

También es una mala practica usar On Error Resume Next (esto siempre es una última opción, y tal vez eso te esta entorpeciendo a la hora de saber cual es el problema en tu macro)

Ahora, algunos consejos a la hora de manipular libros y/o hojas.

1- Usted siempre puede referirse al libro que contiene la macro como ThisWorkbook, así tiene mas control y mejor visualización del código.

2- No tiene que usar la función Window si los únicos archivos que esta manipulando son de Excel. Window se utiliza para manipular la ventana de otro programa que no sea Excel. En su caso usted solo tiene que referirse a los libros por la propiedad workbooks.

3- No tienes que seleccionar un rango para copiarlo, tampoco para pegar. Usted puede simplemente decir Range("B2:BE500"). Copy y luego Range("B2"). Paste

No hay necesidad de seleccionar y luego copiar, y luego seleccionar, y luego pegar.

4-Tampoco tiene que activar un libro para trabajar con él.

Espero que esto le ayude a reparar su macro, y si todavía esta teniendo problemas, déjeme saber y con gusto le ayudo a elaborar una.

Andy M

Andy M, buenos días. Modifique el código pero sigue pegando la información en una sola, a pesar de que trató de darle la instrucción para pegado en diferentes hojas, la verdad no se como organizar esta parte, me podes ayudar a reorganizar uno nuevo, o corregir este, muchas gracias.

Sub Abre_Contratacion()
' Ventana para cargar archivo de Hitos, en una hoja predeterminada en el libro
Application.ScreenUpdating = False
Application.DisplayAlerts = False
On Error Resume Next

Dim miarchivo, milibro, a, b, c As String

ruta = ActiveWorkbook.Path
ChDir ruta
miarchivo = Application.GetOpenFilename("Archivos Excel (*.xl*), *.xl*") 'Código para cargar archivo

'ESTE CÓDIGO ES EN CASO DE CANCELAR LA VENTANA NO ME SALGA EL ERROR Y ME ENVÍE A DEPURAR EL CÓDIGO
If VarType(miarchivo) = vbBoolean Then
MsgBox ("Operación cancelada"), vbCritical, "AVISO"
Exit Sub
End If

milibro = ActiveWorkbook.Name

Workbooks.Open Filename:=miarchivo, UpdateLinks:=0 ' Abrir hitos y cargar datos a Hoja de Hitos
FullName = Split(miarchivo, Application.PathSeparator)

a = FullName(UBound(FullName))
Set b = Sheets(ActiveSheet.Name)

Workbooks(milibro).Sheets("'Hoja8").Select.UsedRange.Copy
Range("A4:BE500").Select
Selection.Copy
Windows("BBDD Autov2.xlsm").Activate
Sheets("Contratacion").Select
Range("A3").Select
ActiveSheet.Paste

Workbooks(milibro).Sheets("Torn Seg PT hito Ant Cumplido").Select.UsedRange.Copy

Range("B28:BX33").Select
Application.CutCopyMode = False
Selection.Copy
Windows("BBDD Autov2.xlsm").Activate
Sheets("PT hito ant cump").Select
Range("B2").Select
ActiveSheet.Paste

Workbooks(milibro).Sheets("Torn Seg PM hito Ant Cumpli").Select.UsedRange.Copy

Range("B28:BE33").Select
Selection.Copy
Windows("BBDD Autov2.xlsm").Activate
Sheets("PM hito ant cump").Select
Range("B2").Select
ActiveSheet.Paste

Application.CutCopyMode = False 'Limpiar el portapapeles
Application.Workbooks.Open(miarchivo).Close 'Cerrar archivo del cual copiamos información
Sheets("Menú").Select

MsgBox "Archivo cargado con éxito", vbInformation, "AVISO"
End Sub

Puedes explicarme los pasos que quieres seguir para poder hacerte la macro. No entiendo tu macro, tiene muchos errores como por ejemplo:

Workbooks(milibro).Sheets("'Hoja8").Select.UsedRange.Copy

Ese código no se que significa, presiento que tu macro deja de funcionar en algún punto por algún error que no ves ya que estás usando On Error Resume Next, así que cualquier error que ocurra lo ignora y esto es fatal en la mayoría de los casos ya que un error puede conllevar a otro y a otro y a otro y jamas te enteras porque los ignora todos y al final tienes una macro que no hace nada.

Explica con pasos lo que quieres, hacer, no pegues un código, solo dime los pasos y yo lo traduzco a código.

Andy M.

Bueno, los pasos son los siguientes

1. En el "milibro" actual tener un botón para abrir otro libro
2. Abrir otro libro
3. Seleccionar hoja
4. Seleccionar rango de celdas para copiar
5. En "mi-libro" seleccionar Hoja 1 determinada, y pegar en un rango donde no me dañe el encabezado.
6.Volver a otro libro
7. Seleccionar otra hoja
8. Seleccionar rango de celdas para copiar
9. En "mi-libro" seleccionar Hoja 2 determinada, y pegar en un rango donde no me dañe el encabezado.
10. El ciclo se repite con 3 o 4 hojas más o menos.
11. Cerrar otro libro
12. Seguir trabajando en "mi-libro"

Así funciona la macro, pero como menciono en el problema, cuando trato de copiar una nueva hoja y pegarla en Hoja 2 por ejemplo, me borra la información anterior en Hoja 1  y pega lo que se supone debe ir en Hoja 2.

Pruebe esta macro, ya que no me dijo los rangos y los nombres de las hojas ni la cantidad exacta de hojas, modifique esos nombres y esos rangos para adaptarlo a sus libros:

Sub AndresElias()
Application.ScreenUpdating = False
Dim SrcPath 'la ruta del libro origen'
Dim wbSrc As Workbook 'el libro origen'
Dim wbDst As Workbook 'el libro donde se pega'
SrcPath = Application.GetOpenFilename("Archivos Excel (*.xl*), *.xl*")
If SrcPath <> False Then
    Set wbDst = ThisWorkbook
    Set wbSrc = Workbooks.Open(SrcPath)
    'primera hoja copia y pega'
    WbSrc. Sheets("Hoja 1"). Range("A1:C2"). Copy
 wbDst. Sheets("Destino 1"). Range("A1"). PasteSpecial
 'segunda hoja copia y pega'
    WbSrc. Sheets("Hoja 2"). Range("A1:C2"). Copy
 wbDst. Sheets("Destino 2"). Range("A1"). PasteSpecial
 'tercera hoja copia y pega'
    WbSrc. Sheets("Hoja 3"). Range("A1:C2"). Copy
 wbDst. Sheets("Destino 3"). Range("A1"). PasteSpecial
 'etc etc'
    WbSrc. Close
Else
    MsgBox "Operación cancelada", vbCritical, "AVISO"
End If
Application.ScreenUpdating = True
End Sub

Note que wbSrc es el libro origen, donde residen los datos que va a copiar.

WbDst es el libro destino donde se pegaran los datos.

Si los rangos fueran igual en todas las hojas, esto se haría con un loop, pero creo que no son los mismos rangos.

Nota que se usa PasteSpecial, ya que Paste no es una propiedad soportada en este caso, y tal vez eso sea uno de los errores que tenias y no lo veías por usar On Error Resume Next.

Andy M.

Añade tu respuesta

Haz clic para o

Más respuestas relacionadas