Reducir macro que copia datos de una libro a otro
Podrían ayudarme a optimizar una macro que me copia datos de un libro a otro, ahora repito la sentencia para cada hoja, pero se ralentiza mucho.
3 Respuestas
                Sub MetodoAbrirLibro()
Dim rngCopy As Range, rngCopyOT2 As Range, rngOT1 As Range, rngOT2 As Range, cel As Range, cel2 As Range, adres$
Dim wbOr As Workbook, wbDes As Workbook
Dim nombre As String, Ruta As String
Application.ScreenUpdating = False
Set wbOr = ThisWorkbook
Set wbDes = Workbooks.Open("C:\Users\jctorres\Desktop\Programaciones vba\Partes presenciales\C2020-0136_Carga_Horas (1)2.xls")
With wbOr.Sheets("EPYC1")
    . Range("A8:F108"). Copy
    WbDes. Sheets("Personal"). Range("A8:F108"). PasteSpecial xlPasteValues
    . Range("F2"). Copy
    WbDes. Sheets("Personal"). Range("G3"). PasteSpecial xlPasteValues
    . Range("I2"). Copy
    WbDes. Sheets("Personal"). Range("H3"). PasteSpecial xlPasteValues
    Set rngOT1 = .Range("A:U")
    Set rngCopy = Intersect(rngOT1, Union(.Range("H2"), .Range("H3"), .Range("l2"), .Range("G8:H108"), .Range("J8:K108"), .Range("M8:M108")))
    For Each cel In rngCopy
        adres = cel.Address
        wbDes.Sheets("OT1").Range(adres).FormulaR1C1 = cel.Value
        Next cel
    End With
With wbOr.Sheets("EPYC2")
    Set rngOT2 = .Range("A:U")
    Set rngCopy = Intersect(rngOT2, Union(.Range("H2"), .Range("H3"), .Range("l2"), .Range("G8:H108"), .Range("J8:K108"), .Range("M8:M108")))
    For Each cel In rngCopy
        adres = cel.Address
        wbDes.Sheets("OT2").Range(adres).FormulaR1C1 = cel.Value
        Next cel
End With
With wbOr.Sheets("EPYC3")
    Set rngOT2 = .Range("A:U")
    Set rngCopy = Intersect(rngOT2, Union(.Range("H2"), .Range("H3"), .Range("l2"), .Range("G8:H108"), .Range("J8:K108"), .Range("M8:M108")))
    For Each cel In rngCopy
        adres = cel.Address
        wbDes.Sheets("OT3").Range(adres).FormulaR1C1 = cel.Value
        Next cel
End With
With wbOr.Sheets("EPYC4")
    Set rngOT2 = .Range("A:U")
    Set rngCopy = Intersect(rngOT2, Union(.Range("H2"), .Range("H3"), .Range("l2"), .Range("G8:H108"), .Range("J8:K108"), .Range("M8:M108")))
    For Each cel In rngCopy
        adres = cel.Address
        wbDes.Sheets("OT4").Range(adres).FormulaR1C1 = cel.Value
        Next cel
End With
With wbOr.Sheets("EPYC5")
    Set rngOT2 = .Range("A:U")
    Set rngCopy = Intersect(rngOT2, Union(.Range("H2"), .Range("H3"), .Range("l2"), .Range("G8:H108"), .Range("J8:K108"), .Range("M8:M108")))
    For Each cel In rngCopy
        adres = cel.Address
        wbDes.Sheets("OT5").Range(adres).FormulaR1C1 = cel.Value
        Next cel
End With
With wbOr.Sheets("EPYC6")
    Set rngOT2 = .Range("A:U")
    Set rngCopy = Intersect(rngOT2, Union(.Range("H2"), .Range("H3"), .Range("l2"), .Range("G8:H108"), .Range("J8:K108"), .Range("M8:M108")))
    For Each cel In rngCopy
        adres = cel.Address
        wbDes.Sheets("OT6").Range(adres).FormulaR1C1 = cel.Value
        Next cel
End With
With wbOr.Sheets("EPYC7")
    Set rngOT2 = .Range("A:U")
    Set rngCopy = Intersect(rngOT2, Union(.Range("H2"), .Range("H3"), .Range("l2"), .Range("G8:H108"), .Range("J8:K108"), .Range("M8:M108")))
    For Each cel In rngCopy
        adres = cel.Address
        wbDes.Sheets("OT7").Range(adres).FormulaR1C1 = cel.Value
        Next cel
End With
With wbOr.Sheets("EPYC8")
    Set rngOT2 = .Range("A:U")
    Set rngCopy = Intersect(rngOT2, Union(.Range("H2"), .Range("H3"), .Range("l2"), .Range("G8:H108"), .Range("J8:K108"), .Range("M8:M108")))
    For Each cel In rngCopy
        adres = cel.Address
        wbDes.Sheets("OT8").Range(adres).FormulaR1C1 = cel.Value
        Next cel
End With
Application.CutCopyMode = False
End Sub
El codigo
- Compartir respuesta
 
        Puedes utilizar las áreas de un rango para pasar todo el rango de celdas, en lugar de hacerlo por celda.
Si en lugar de copiar y pegar, pasas los valores, el proceso será más rápido.
Revisa esta opción:
Sub MetodoAbrirLibro_2()
  Dim wbOr As Workbook, wbDes As Workbook
  Dim ar As Range
  Dim i As Long
  '
  Set wbOr = ThisWorkbook
  Set wbDes = Workbooks.Open("C:\Users\jctorres\Desktop\Programaciones vba\Partes presenciales\C2020-0136_Carga_Horas (1)2.xls")
  With wbOr.Sheets("EPYC1")
    wbDes.Sheets("Personal").Range("A8:F108").Value = .Range("A8:F108").Value
    wbDes.Sheets("Personal").Range("G3").Value = .Range("F2").Value
    wbDes.Sheets("Personal").Range("H3").Value = .Range("I2").Value
  End With
  '
  For i = 1 To 8
    With wbOr.Sheets("EPYC" & i)
      For Each ar In Union(.Range("H2"), .Range("H3"), .Range("l2"), .Range("G8:H108"), .Range("J8:K108"), .Range("M8:M108")).Areas
        wbDes.Sheets("OT" & i).Range(ar.Address).Value = ar.Value
      Next ar
    End With
  Next i
End Sub
                    - Compartir respuesta
 
        La macro se puede reducir con el uso de un bucle For ... Next, de este modo:
Sub MetodoAbrirLibro()
Dim rngCopy As Range, rngCopyOT2 As Range, rngOT1 As Range, rngOT2 As Range, cel As Range, cel2 As Range, adres$
Dim wbOr As Workbook, wbDes As Workbook
Dim nombre As String, Ruta As String
Application.ScreenUpdating = False
Set wbOr = ThisWorkbook
Set wbDes = Workbooks.Open("C:\Users\jctorres\Desktop\Programaciones vba\Partes presenciales\C2020-0136_Carga_Horas (1)2.xls")
With wbOr.Sheets("EPYC1")
    . Range("A8:F108"). Copy
    WbDes. Sheets("Personal"). Range("A8:F108"). PasteSpecial xlPasteValues
    . Range("F2"). Copy
    WbDes. Sheets("Personal"). Range("G3"). PasteSpecial xlPasteValues
    . Range("I2"). Copy
    WbDes. Sheets("Personal"). Range("H3"). PasteSpecial xlPasteValues
End With
For i = 1 To 8
    nbreHo1 = "EPYC" & i
    nbreHo2 = "OT" & i
    With wbOr.Sheets(nbreHo1)
        Set rngOT1 = .Range("A:U")
        Set rngCopy = Intersect(rngOT1, Union(.Range("H2"), .Range("H3"), .Range("l2"), .Range("G8:H108"), .Range("J8:K108"), .Range("M8:M108")))
        For Each cel In rngCopy
            wbDes.Sheets(nbreHo2).Range(cel.adres) = cel.Value
            Next cel
        End With
    End With
Next i
Application.CutCopyMode = False
End SubObserva que para la hoja EPYC1 la primer parte se mantiene y solo entra al bucle desde la definición del rango 'rngOT1'
Ahora, el tiempo de demora también se debe al modo de copiar/pegar, que vas haciendo celda x celda. Pero no puedo hacer cambios allí ya que desconozco cómo es cada rango (con formato, con fórmulas, combinadas o no, etc).
Debes copiar el código TAL COMO se te envía:
wbDes.Sheets(nbreHo2).Range(cel.adres) = cel.Value
Cuando se utiliza una variable para indicar el nombre de un libro u hoja, NO va entre comillas.
Sdos!
Si está configurada la opción de exigir la declaración de variables (generalmente ya no la utilizamos), al inicio debes agregar también estas líneas:
Dim i as Byte
Dim nbreHo1 as String, nbreHo2 as String
Sdos. Recuerda que tienes 2 opciones para votar: Buena o Excelente ;)
Elsa
Cópiala tal cual:
Sub MetodoAbrirLibro()
Dim rngCopy As Range, rngOT1 As Range, cel As Range, cel2 As Range, adres$
Dim wbOr As Workbook, wbDes As Workbook
Dim nombre As String, Ruta As String
Dim i As Byte
Dim nbreHo1 As String, nbreHo2 As String
Application.ScreenUpdating = False
Set wbOr = ThisWorkbook
Set wbDes = Workbooks.Open("C:\Users\jctorres\Desktop\Programaciones vba\Partes presenciales\C2020-0136_Carga_Horas (1)2.xls")
With wbOr.Sheets("EPYC1")
    . Range("A8:F108"). Copy
    WbDes. Sheets("Personal"). Range("A8:F108"). PasteSpecial xlPasteValues
    . Range("F2"). Copy
    WbDes. Sheets("Personal"). Range("G3"). PasteSpecial xlPasteValues
    . Range("I2"). Copy
    WbDes. Sheets("Personal"). Range("H3"). PasteSpecial xlPasteValues
End With
For i = 1 To 8
    nbreHo1 = "EPYC" & i
    nbreHo2 = "OT" & i
    With wbOr.Sheets(nbreHo1)
        Set rngOT1 = .Range("A:U")
        Set rngCopy = Intersect(rngOT1, Union(.Range("H2"), .Range("H3"), .Range("l2"), .Range("G8:H108"), .Range("J8:K108"), .Range("M8:M108")))
        For Each cel In rngCopy
            adres = cel.Address
            wbDes.Sheets(nbreHo2).Range(adres).FormulaR1C1 = cel.Value
            Next cel
        End With
    End With
Next i
Application.CutCopyMode = False
End SubSi te da algún error presioná el botón DEpurar y tomá captura de imagen del Editor para que vea en qué línea se detiene y el mensaje que te devuelve.
Sdos!
                Ahora si que funciona, pero no sigue igual de lento. Sera lo que dijiste sobre copiar y pegar los datos en las celdas.
Ahora si que funciona, pero no sigue igual de lento... je je... Esas fueron tus palabras y por eso no continué el tema ;)
Reducir la macro fue la solicitud... y no me detuve a mejorar el pase ya que eso requería, quizás, de mayores aclaraciones. Como bien dice el otro experto, siempre es más ágil copiar por rangos o áreas que fila por fila.
Pero a veces los usuarios quieren solo valores (sin fórmulas), otras veces quieren mantener, o no, los formatos... por lo que el tema requería de mayores aclaraciones. Qué bueno que lo tuyo era un pase simple nomás.
Sdos!
- Compartir respuesta
 
        