excel excel-vba vba

Error13 en Excel VBA en archivo de datos



excel-vba (1)

En aras de la curiosidad y el ejercicio intelectual, tomé una puñalada en el método de procesamiento de matriz presentado originalmente por ZygD en la pregunta original con la ZygD de superar el error de tiempo de ejecución ''13'': error de desajuste de tipo en conjuntos de datos más grandes.

La instrucción ReDim Preserve solo puede redimensionar el último rango mientras conserva los valores existentes ya almacenados, sujeto al hecho de que está aumentando el tamaño de la dimensión de la matriz y no la reduce. Esto es lo que msdn.microsoft.com tiene para decir sobre el tema:

Redimensionando con Preserve . Si usa Conservar, solo puede cambiar el tamaño de la última dimensión de la matriz. Para cada otra dimensión, debe especificar el límite de la matriz existente.
Por ejemplo, si su matriz tiene solo una dimensión, puede cambiar el tamaño de esa dimensión y aún preservar todo el contenido de la matriz, porque está cambiando la última y única dimensión. Sin embargo, si su matriz tiene dos o más dimensiones, puede cambiar el tamaño de solo la última dimensión si usa Conservar.

Debido a la orientación de los datos pelados de la hoja de trabajo, el primer rango fue la dimensión para crecer con ReDim, por lo que la orientación se volcó con Application.Transpose, ReDim''ed con Preserve y luego volteó hacia atrás. A medida que la matriz creció con registros adicionales, Application.Transpose alcanzó rápidamente su capacidad máxima para reorientar la matriz. Encontré algo de documentación anterior sobre esto en XL: Limitaciones de pasar matrices a Excel usando la automatización, pero está terriblemente desactualizado.

Mi solución fue transponer los valores de ar1 a ar2 sobre la marcha para que ar2 pudiera redimensionarse sin reorientación. Una vez que se completó el procesamiento, los resultados estaban en la orientación incorrecta. Para recuperar los valores en la hoja de trabajo en la orientación correcta, escribí una función auxiliar que transpuso ar2 nuevo a un ar1 truncado. Esta pseudo-transposición solo se necesitaba una vez; justo antes de volver a introducir los nuevos valores agregados en el área de informes.

Subcódigo modificado:

Sub jpd_Transposing() Const sDestination As String = "D2" Dim ar1 As Variant Dim ar2 As Variant Dim i As Long ''counter With ActiveSheet ar1 = .Range("A2:B" & .Cells(Rows.Count, 1).End(xlUp).Row).Value ReDim ar2(1 To 2, 1 To 1) ar2(1, 1) = ar1(1, 1): ar2(2, 1) = ar1(1, 2) For i = 2 To UBound(ar1, 1) If ar1(i, 1) = ar2(1, UBound(ar2, 2)) Then ar2(2, UBound(ar2, 2)) = ar2(2, UBound(ar2, 2)) & ar1(i, 2) ElseIf ar1(i, 1) = vbNullString Then ar2(2, UBound(ar2, 2)) = ar2(2, UBound(ar2, 2)) & " " Else ReDim Preserve ar2(1 To 2, 1 To UBound(ar2, 2) + 1) ar2(1, UBound(ar2, 2)) = ar1(i, 1) ar2(2, UBound(ar2, 2)) = ar1(i, 2) End If Next ar1 = my_2D_Transpose(ar1, ar2) .Range(sDestination).Resize(UBound(ar1, 1), UBound(ar1, 2)) = ar1 End With End Sub Function my_2D_Transpose(a1 As Variant, a2 As Variant) Dim a As Long, b As Long ReDim a1(1 To UBound(a2, 2), 1 To UBound(a2, 1)) For a = LBound(a2, 1) To UBound(a2, 1) For b = LBound(a2, 2) To UBound(a2, 2) a1(b, a) = Trim(a2(a, b)) Next b Next a my_2D_Transpose = a1 End Function

Entonces, ahora se preguntará cuánta mejora sobre la rutina basada en la hoja de trabajo original había con el procesamiento de memoria ordenada. Como ese era el siguiente paso lógico, ejecuté ambos con un temporizador que indicaba iniciar y detener.

Sub timed() Application.ScreenUpdating = False Application.EnableEvents = False Debug.Print Timer Call concatenate_and_transpose_to_delim_string Debug.Print Timer Call jpd_Transposing Debug.Print Timer Application.EnableEvents = True Application.ScreenUpdating = True End Sub

Los dos resultados de los datos del informe fueron idénticos. Tenga en cuenta que apagué la actualización de pantalla y el manejo de eventos durante la prueba. Esto probablemente mejoró el método de la hoja de trabajo más de lo que mejoró el método de matriz, pero pensé que era justo dado que estas son técnicas bastante estándar para mejorar la eficiencia de una macro.

Resultados cronometrados:

Entorno de prueba: 45.894 filas × 2 columnas de datos sin procesar convertidos a 123 filas × 2 columnas de datos de informes agregados utilizando una computadora portátil basada en clase empresarial i5 / 8Gb (Win7, Excel 2010 versión 14.0.7145.5000 (32 bits)

concatenate_and_transpose_to_delim_string (hoja de trabajo) .... 00: 01.01 segundos¹
jpd_Transposing (matriz de memoria) ............................................. .. 00: 00.07 segundos¹

¹ La prueba se ejecutó varias veces. Los tiempos son típicos.

Conclusiones:

Bien, entonces tomamos casi un segundo completo usando una matriz de memoria variante sobre la lectura / escritura de la hoja de trabajo, pero eso sigue siendo una mejora del 93% en la eficiencia del procesamiento de datos idénticos a resultados idénticos. He convertido otras rutinas de larga duración de la hoja de trabajo dirigida a la memoria ordenada; los resultados fueron al menos tan apreciables y se dedicaron a operaciones de búsqueda más repetitivas en grandes matrices de datos.

¿Valió la pena? Eso depende más o menos del usuario individual y la situación. Ciertamente, se pueden obtener beneficios, pero escribo código basado en hojas de trabajo mucho más rápido que el código basado en matriz, por lo que a menos que esto se ejecute varias veces al día todos los días, probablemente no me molestaría. El tamaño del proyecto también sería un factor, ya que los beneficios aumentarían con la cantidad de trabajo a realizar. Aún así, es bueno mantener los métodos utilizados con los métodos de matriz de memoria frescos en la mente y una combinación de métodos puede producir el mejor resultado en algunos casos.

FWIW, la función VBA Trim utilizada en la función auxiliar de transposición no produjo ningún efecto perjudicial medible (por ejemplo, tiempo adicional) si se usó o no y parecía el mejor lugar para asegurarse de que el resultado final no tuviera un carácter de espacio restante de la cadena concatenación.

Estoy ejecutando el código VBA a continuación en el siguiente archivo:

http://www.filedropper.com/error13

Me sale un error 13 No coinciden los tipos.

Aquí está la macro

Agregar, clasificar y transponer filas en columnas

Funciona bien cuando selecciono algunas de las filas (por ejemplo, id 1001 o 1003 y 1004 juntas, pero cuando trato de procesar más filas me sale el error 13.

Estoy tratando de procesar cada identificación a la vez, pero tengo alrededor de 100 ...