2011-05-18 34 views
7

Tengo una fórmula de matriz que genera un solo valor, y quiero darle a un montón de celdas esta misma fórmula de matriz. El problema es que cuando asigno la fórmula de matriz al rango, interpreta la fórmula de tal manera que todos comparten la salida de una sola llamada a la fórmula de matriz, en lugar de que cada uno de ellos genere un valor por separado.Establezca ArrayFormula en muchas celdas de Excel usando VBA

para mostrar lo que quiero decir, estoy usando el siguiente código:

With MarginalData 
    .Range(.Cells(2, 1), .Cells(13, .UsedRange.Columns.Count)).FormulaArray = pullFormula 
End With 

Lo que quiero, es un resultado que se ve así: desired result

Eso es lo que se parece cuando ingreso la fórmula de matriz por separado en cada celda del rango.

Pero lo que me pasa es la siguiente: given result

La salida de la fórmula de matriz en la primera celda se repite en todas las columnas - todos ellos comparten la misma salida.

¿Cómo puedo asignar programáticamente la fórmula de matriz como si cada celda la tuviera asignada por separado?


La fórmula es:

{= índice (BatchResults, Partido (TTID & CHAR (1) & ROW() - 1, BatchResultsTTIDS & CHAR (1) & BatchResultsLayers, 0), (! a $ 1, BatchTTIDData $ 1: $ 1,0) pARTIDO)}

será metido en como una fórmula de matriz, ya que realiza un fósforo no en una sola columna, pero en dos columnas concatenadas. La concatenación de las columnas se debe devolver como una matriz, por lo tanto, la fórmula se debe ingresar como una fórmula de matriz.


La solución más simple hasta el momento, una variante de la respuesta aceptada a continuación, es el siguiente:

Const pullFormula = "=INDEX(BatchResults,MATCH(TTID&CHAR(1)&ROW()-1,BatchResultsTTIDS&CHAR(1)&BatchResultsLayers,0),MATCH(A$1,BatchTTIDData!$1:$1,0))" 
With wrksht 
    With .Range(.Cells(2, 1), .Cells(13, .UsedRange.Columns.Count)) 
     .Formula = pullFormula 
     .FormulaArray = .FormulaR1C1 
    End With 
End With 
+0

Necesita ser capaz de hacer depender 'pullFormula' en la celda que se encuentra, pero necesitamos la cadena para que eso le mostrará cómo hacer que eso suceda (si es posible). –

+0

Como puede ver arriba, pullFormula ya depende de la celda en la que se encuentra. Tiene en cuenta la fila actual y el encabezado de columna ('A $ 1'), que es diferente para cada columna. – Alain

+0

Buena pregunta. Y según [este artículo] (http: //colinlegg.wordpress.com/2012/05/23/working-with-range-formulaarray-in-vba /) tiene el mejor enfoque – brettdj

Respuesta

5

o recoger la matriz Fórmula como R1C1, asigne al rango como FormulaR1C1, luego asigne el FormulaR1C1 como fórmula de matriz. Esto supone que la fórmula del arreglo está en la celda A2

Sub test() 

With Sheet1 
    pullFormula = .Range("A2").FormulaR1C1 
    Set Rng = .Range(.Cells(2, 1), .Cells(13, .UsedRange.Columns.Count)) 

    Rng.Formula = pullFormula 
    Rng.FormulaArray = Rng.FormulaR1C1 

End With 
End Sub 
+0

Esta solución funciona, pero sucede lo más extraño, cuando se establece la matriz de fórmulas igual que en form1c1, la operación es increíblemente lenta, incluso más lenta que el bucle de todas las células manualmente, que es lo que parece estar haciendo si ejecuta la línea de código con la actualización de la pantalla activada. – Alain

+0

@Alain Ouch que es bastante lento en grandes distancias! Tal vez sería más rápido usar mi método para la primera fila solo luego rellenar automáticamente EG Rng.AutoFill Destination: = Rng.Resize (999, Rng.Columns.Count), Type: = xlFillDefault. O usando 'Application.Calculation = xlCalculationManual' es un poco más rápido – osknows

2

en lugar de un $ 1, tratar

INDIRECT(ADDRESS(1,COLUMN())) 
+1

No sé por qué esto fue votado tanto, COL() ni siquiera es una función válida en excel: la función que querías decir era COLUMN(). Además, ADDRESS devuelve una cadena "$ A $ 1", "$ B $ 1", etc. La función MATCH toma un rango, no una cadena. Colocar eso en la función lo rompe. – Alain

+1

Eso no es todo lo que está mal, para que esta función funcione después de convertir la referencia en una cadena, uno se ve obligado a usar la función INDIRECTO, que es volátil y significa que estas fórmulas costosas de matriz se volverán a calcular cada vez que haya algo cambiado en el libro de trabajo, lo cual es terriblemente inaceptable. – Alain

+0

E incluso si alguien aguanta la fórmula INDIRECTA, su cambio TODAVÍA no logra nada, toda la gama todavía se trata como si tuviera una sola salida, y se produce el mismo problema repetitivo en lugar de que cada celda obtenga su propio valor. – Alain

1

Trate de hacerlo de forma semiautomática. Establezca la fórmula para la primera fila, luego use FillDown.

Private Sub soCopyFormula() 

    Dim MarginalData As Worksheet 
    Set MarginalData = ActiveWorkbook.Worksheets("Sheet2") 
    Dim oRange As Range 
    Dim i As Integer 

    With MarginalData 
     Set oRange = .Range(.Cells(2, 1), .Cells(13, .UsedRange.Columns.Count)) 
     ' for each column 
     For i = 0 To oRange.Columns.Count - 1 
      ' set first row 
      oRange(1, i).FormulaArray = pullFormula 
      ' copy down 
      oRange.Columns(i).FillDown 
     Next 
    End With 

End Sub 
+0

Esta solución funciona pero es más intrincada de lo que yo quiero. Mi solución temporal fue en realidad un poco más simple que esto, que consiste en establecer la fórmula en una celda, copiarla y luego copiarla. – Alain

+0

@Alain Sí, definitivamente una solución. Realmente no he usado FormulaR1C1, pero lo recordaré ahora. –

Cuestiones relacionadas