2012-07-30 23 views
5

He visto a algunos usuarios de SO tener un problema al intentar usar alguna variación de Cells.Count; el código de VBA arroja un error de desbordamiento en algunos casos.Valor incorrecto al contar celdas en diferentes versiones de Excel

Como referencia, véanse los comentarios sobre this answer:

Creo que esto va a funcionar, pero me da un error de "desbordamiento" y me apunta al código "Si Master.Cells.SpecialCells (xlCellTypeVisible) .count> 0 Entonces " --- parece que no se ha filtrado nada en particular - user1556069

y this answer:

¿Funciona esto onyl (y Cells.Count no funcionó) porque el último usó un número entero, 16 bits, valor máximo de 65.536 y la hoja de cálculo completa devolvió un numbr mayor? - fast_code


asumo que en algún lugar detrás de las escenas de VBA está tratando de coaccionar el recuento de células a un pequeño número entero (16 bits) o entero largo (de 32 bits). El recuento de celdas de una hoja de cálculo de Excel 2007 desbordaría ambos tipos de datos . Desafortunadamente no puedo aislarlo ahora porque no tengo tenga una copia de Excel 2007 a mano y no pueda reproducir realmente su error . - mwolfe02

Tratando de entender esto, he intentado reproducir mí mismo y tengo un desbordamiento cuando se trata de asignar Cells.Count como un entero. Esto tiene sentido ya que el valor es demasiado grande para el tipo de datos Integer.

Usando el código a continuación en Excel 2003 y 2010, se me dio un resultado numérico al intentar asignarlo como Long o Variant.

Option Explicit 

Sub testInteger() 
    Dim i As Integer 
    i = Cells.Count 'Overflow 
    Debug.Print i 'Doesn't get this far... 
End Sub 

Sub testLong() 
    Dim l As Long 
    l = Cells.Count 
    Debug.Print l 'Prints 16777216 in both versions 
End Sub 

Sub testVariant() 
    Dim v As Variant 
    v = Cells.Count 
    Debug.Print v 'Prints 16777216 in both versions 
End Sub 

Como se puede ver en mis comentarios, el valor es Cells.Count16777216 (que es correcto para el 2003), pero es el mismo para ambas versiones , y que no tiene sentido para mí. Para citar mwolfe02 de una de las respuestas anteriormente vinculado:

Excel 2007 hojas de trabajo tienen 1.048.576 filas y 16.384 columnas para un total de 17,179,869,184 células.

Lo que me dice que el valor impreso en 2010 debería ser al menos (creo que debería ser el mismo) 17,179,869,184.

¿Por qué este número no se imprime correctamente/por qué se devuelve el valor de 2003 en 2010?

+2

16777216 es '0x1000000' y 17179869184 es' 0x400000000' en hexadecimal solo FYI. – TheZ

+0

¿Está ejecutando Excel 2010 en modo Compatability o mirando un archivo guardado en formato 2003? –

+0

@TimWilliams Comencé abriendo una nueva sesión de Excel 2010, que de manera predeterminada era Book1, en la que pegué el código anterior. ¿Cómo puedo determinar si estoy en compatibilidad? ¿modo? – Gaffi

Respuesta

7

Al calcular números tan grandes, utilice la propiedad .Countlarge.

Por ejemplo

Sub CellsCount() 
    Dim l As Double 
    l = ActiveSheet.Cells.CountLarge 
    Debug.Print l 
End Sub 

Además, nunca utilizar Cells.Count o Cells.CountLarge sin especificar el objeto de hoja. Esto es para garantizar que no obtengamos un recuento/error incorrecto en el modo de compatibilidad. Del mismo modo, nunca use Rows.Count. Siempre use ws.Rows.Count. Este es el error más común que las personas hacen al tratar de encontrar la última fila en Excel. Por ejemplo

Este

lRow = ws.Range("A" & Rows.Count).End(xlUp).Row 

y

lRow = ws.Range("A" & ws.Rows.Count).End(xlUp).Row 

no le puede dar los mismos resultados siempre.

También recomendaría una lectura adicional de this.

+0

Gracias, Sid. Aprecio tu visión. (Aún así, ¿por qué MSFT tiene que tener tanto '.Count' * y *' .CountLarge' ...?) – Gaffi

+2

Es como preguntar por qué MS tiene Excel 2003 y Excel 2007: P. '.CountLarge' se introdujo con Excel 2007 y no estaba disponible con versiones anteriores de Excel. La propiedad 'Count' usa Long Data Type, por lo que el mayor valor que puede almacenar es 2.147.483.647. '.CountLarge' usa el Tipo de datos doble que puede manejar hasta 1.79 + E^308. –

+1

+1: para compatibilidad con versiones anteriores puede incluir un cheque basado en 'val (application.version)> = 12' y usar Cells.Countlarge si es verdadero y Cells.Count de lo contrario. Tenga en cuenta que si utiliza los dobles para almacenar enteros, también puede alcanzar un límite debido a los 15 dígitos de precisión ~ 2^50, pero esto supera con creces el tamaño de la cuadrícula 2^20 * 2^14 = 2^34. –

Cuestiones relacionadas