Un problema habitual con el que nos encontramos es cuando al trabajar sobre un volumen alto de campos o columnas, necesitamos recuperar algunas de ellas... optando por la vía fácil de crear una línea por variable (fácil y ágil).
Por supuesto existen algunas alternativas, y hoy veremos una de ellas.
Supongamos un tabla con muchos campos, en el ejemplo nos quedaremos con una columna por mes:
El objetivo es recuperar las empresas solo de 'ES' y sus datos acumulados por trimestre y año (operaciones que realizará la macro).
Para ello nos apoyaremos en la función VBA (poco conocida) CallByName que ejecuta un método de un objeto, o bien establece o devuelve una propiedad de un objeto.
Su sintáxis:
CallByName( objecto , procname, calltype [, args()])
Objeto: (obligatorio). Tipo Object. El nombre del objeto en el que se ejecutará la función.
procname:(obligatorio). Tipo String. Expresión de cadena que contiene el nombre de una propiedad o método del objeto.
calltype: (bligatorio). Tipo Constante. Una constante de tipo vbCallType que representa el tipo de procedimiento al que se llama.
args(): (opcional). Tipo Variant(matriz).
Para facilitar la conversión y el tratamiento de objetos crearemos un Módulo de clase con una sencilla línea:
A este módulo de clase lo he llamado 'clsEMP'
Ya podemos desarrollar nuestro código en un módulo estándar:
Un buen método de trabajo si el número de variables con el trabajar es alto; además es bastante claro, ya que quedan muy detalladas en cuanto número, nombre y orden en nuestra matriz 'arr'.
Una alternativa más que conviene considerar.
Por supuesto existen algunas alternativas, y hoy veremos una de ellas.
Supongamos un tabla con muchos campos, en el ejemplo nos quedaremos con una columna por mes:
El objetivo es recuperar las empresas solo de 'ES' y sus datos acumulados por trimestre y año (operaciones que realizará la macro).
Para ello nos apoyaremos en la función VBA (poco conocida) CallByName que ejecuta un método de un objeto, o bien establece o devuelve una propiedad de un objeto.
Su sintáxis:
CallByName( objecto , procname, calltype [, args()])
Objeto: (obligatorio). Tipo Object. El nombre del objeto en el que se ejecutará la función.
procname:(obligatorio). Tipo String. Expresión de cadena que contiene el nombre de una propiedad o método del objeto.
calltype: (bligatorio). Tipo Constante. Una constante de tipo vbCallType que representa el tipo de procedimiento al que se llama.
args(): (opcional). Tipo Variant(matriz).
Para facilitar la conversión y el tratamiento de objetos crearemos un Módulo de clase con una sencilla línea:
Public dato As Variant
A este módulo de clase lo he llamado 'clsEMP'
Ya podemos desarrollar nuestro código en un módulo estándar:
Sub PasarTextoComoVariable_OLD() 'nos referimos a la tabla de la hoja1 Set tb = Hoja1.ListObjects(1) Dim arrFINAL() As Variant 'definimos la matriz final que recopilará los datos que nos interesen 'comenzamos el bucle por la tabla x = 0 For Each emp In Hoja1.Range("TblDATOS[empresa]") x = x + 1 'aplicamos la condición del país buscado If UCase(Hoja1.Range("TblDATOS[País]").Item(x).Value) = "ES" Then 'y asignamos valor a nuestras 19 variables '(y, sí... hay otra forma de hacerlo más sencillo) empresa = tb.DataBodyRange.Cells(x, tb.ListColumns("empresa").Index).Value pais = tb.DataBodyRange.Cells(x, tb.ListColumns("país").Index).Value ene = tb.DataBodyRange.Cells(x, tb.ListColumns("ene").Index).Value feb = tb.DataBodyRange.Cells(x, tb.ListColumns("feb").Index).Value mar = tb.DataBodyRange.Cells(x, tb.ListColumns("mar").Index).Value Q1 = ene + feb + mar abr = tb.DataBodyRange.Cells(x, tb.ListColumns("abr").Index).Value may = tb.DataBodyRange.Cells(x, tb.ListColumns("may").Index).Value jun = tb.DataBodyRange.Cells(x, tb.ListColumns("jun").Index).Value Q2 = abr + may + jun jul = tb.DataBodyRange.Cells(x, tb.ListColumns("jul").Index).Value ago = tb.DataBodyRange.Cells(x, tb.ListColumns("ago").Index).Value sep = tb.DataBodyRange.Cells(x, tb.ListColumns("sep").Index).Value Q3 = jul + ago + sep octb = tb.DataBodyRange.Cells(x, tb.ListColumns("oct").Index).Value nov = tb.DataBodyRange.Cells(x, tb.ListColumns("nov").Index).Value niv = tb.DataBodyRange.Cells(x, tb.ListColumns("dic").Index).Value Q4 = octb + nov + dic YYYY = Q1 + Q2 + Q3 + Q4 'matriz con los datos que nos interesa trabajar Dim arr() As Variant arr = Array(empresa, Q1, Q2, Q3, Q4, YYYY) 'recorremos los campos a recuperar For i = LBound(arr) To UBound(arr) 'creando un objeto con cada uno de ellos Set valor = New clsEMP 'usamos nuestro módulo de clase valor.dato = arr(i) 'cargamos el objeto con el valor asignado 'para finalmente con CallByName obtener el valor del objeto 'y asignarlo a nuestra matriz final ReDim Preserve arrFINAL(0 To 5, 0 To incremento) As Variant arrFINAL(i, incremento) = CallByName(valor, "dato", VbGet) Next i incremento = incremento + 1 Set valor = Nothing End If Next emp 'devolvemos los datos a la hoja... Hoja1.Range("B10").Resize(incremento, 6).Value = Application.Transpose(arrFINAL()) Set tb = Nothing End Sub
Un buen método de trabajo si el número de variables con el trabajar es alto; además es bastante claro, ya que quedan muy detalladas en cuanto número, nombre y orden en nuestra matriz 'arr'.
Una alternativa más que conviene considerar.
No hay comentarios:
Publicar un comentario
Nota: solo los miembros de este blog pueden publicar comentarios.