VBA: ¿Hay una manera de dar un tiempo de SetClipboard para limpiar?

Cada vez que ejecuto el código me da un mensaje de error de Run Time ("Error de tiempo extra '91". Variable de objetos o con variable de bloque no se establece") cuando se va a un tablero de recortes que se establece. Sin embargo, si si sigo el código paso a paso (utilizando el paso a paso), no tiene ningún problema. El código es uno de muchos bucles que llama al portapapeles. Esto me llevó a creer que era un problema de tiempo, así que cambié el tiempo de 3 segundos a 10. Esto funcionó pero es muy inconsistente, una vez funcionará y otra no lo hará.

Sé que tiene que ver con el Clipboard no tener suficiente tiempo para vaciarse porque no es solo una declaración. Puede ser cualquier declaración que llame al Clipboard. Si lo ejecuto, podría ser la primera declaración de portapapeles que causa el error, o la próxima vez que lo ejecuto, la quinta declaración de llamada de Clipboard podría causar el problema. El único denominador común es el Clipboard.

            DoEvents
            D.Body.InnerHTML = H.responseText
            If Err.Number = "91" Then
                Err.Clear
            Else
                SetClipboard (D.getElementsByTagName("table")(1).outerHTML): Application.Wait (Now + TimeValue("0:00:10")): DoEvents
                Range("Q" & LR).Select
                Sheet17.PasteSpecial Format:="Text", Link:=False, DisplayAsIcon:=False, NoHTMLFormatting:=True
            End If
            Start_Date = Start_Date + 1
            End_Date = Start_Date + 1
            LR = Cells(Rows.Count, "Q").End(xlUp).Row + 1
        Next i

Pregunta hecha hace 3 años, 4 meses, 27 días - Por gitguru


2 Respuestas:

  • El error que estás experimentando parece estar relacionado con la gestión del portapapeles en VBA. Una solución para manejar el problema del tiempo entre las operaciones de copiar y pegar en el portapapeles es utilizar una función que verifique si el portapapeles está disponible antes de intentar utilizarlo.

    Aquí te dejo una función que puedes agregar a tu código para esperar a que el portapapeles esté disponible antes de realizar operaciones con él:

    vba
    Function ClipboardAvailable() As Boolean
        Dim clipboard As MSForms.DataObject
        Set clipboard = New MSForms.DataObject
        On Error Resume Next
        clipboard.GetFromClipboard
        ClipboardAvailable = (Err.Number = 0)
        Err.Clear
        On Error GoTo 0
        Set clipboard = Nothing
    End Function
    

    Luego, puedes modificar tu código de la siguiente manera para incluir una verificación de disponibilidad del portapapeles antes de copiar y pegar:

    vba
    DoEvents
    D.Body.InnerHTML = H.responseText
    If Err.Number = 91 Then
        Err.Clear
    Else
        Do While Not ClipboardAvailable
            Application.Wait (Now + TimeValue("0:00:01"))
        Loop
        SetClipboard (D.getElementsByTagName("table")(1).outerHTML)
        Application.Wait (Now + TimeValue("0:00:10"))
        DoEvents
        Range("Q" & LR).Select
        Sheet17.PasteSpecial Format:="Text", Link:=False, DisplayAsIcon:=False, NoHTMLFormatting:=True
    End If
    Start_Date = Start_Date + 1
    End_Date = Start_Date + 1
    LR = Cells(Rows.Count, "Q").End(xlUp).Row + 1
    

    Al agregar la función ClipboardAvailable y realizar una espera activa hasta que el portapapeles esté disponible, puedes evitar el error de tiempo extra al intentar acceder al portapapeles en VBA de manera más consistente. Asegúrate de ajustar los tiempos de espera según tus necesidades.

    Respondida el Dec 21, 2020 a las 17:14 - por Gpt

    Votos positivos: 0 | Votos negativos: 0

  • El error "Variable de objeto o variable de bloque no establecida" generalmente ocurre cuando se intenta utilizar una variable que no ha sido inicializada o asignada. En tu caso, parece que el error se produce al intentar establecer el portapapeles con SetClipboard.

    Una posible solución para este problema es utilizar la función Clipboard.SetText en lugar de SetClipboard. Clipboard.SetText establece el texto en el portapapeles sin utilizar una variable de objeto.

    Aquí tienes el código modificado:

    vba
                DoEvents
                D.Body.InnerHTML = H.responseText
                If Err.Number = "91" Then
                    Err.Clear
                Else
                    Clipboard.SetText D.getElementsByTagName("table")(1).outerHTML
                    Application.Wait (Now + TimeValue("0:00:10")): DoEvents
                    Range("Q" & LR).Select
                    Sheet17.PasteSpecial Format:="Text", Link:=False, DisplayAsIcon:=False, NoHTMLFormatting:=True
                End If
                Start_Date = Start_Date + 1
                End_Date = Start_Date + 1
                LR = Cells(Rows.Count, "Q").End(xlUp).Row + 1
            Next i
    

    También puedes intentar aumentar el tiempo de espera utilizando Application.Wait o utilizar un bucle Do While para comprobar si el portapapeles está vacío antes de continuar.

    Además, asegúrate de que el objeto D y sus propiedades estén inicializados correctamente antes de intentar acceder a ellos.

    Respondida el Dec 21, 2020 a las 17:18 - por Gemini

    Votos positivos: 0 | Votos negativos: 0