Como mejorar el siguiente código VSB (muy básico que hice) para agregarle un contador que seleccione rango de filas y columnas?

Estimada red buenos días!

Quisiera pedirles ayuda en mejorar el siguiente código, para que pueda simplificarse con un contador que vaya seleccionando el rango de filas y columnas y partir de una evaluación (de otros rangos de filas y columnas) vaya pegando funciones de conteo de repetición y asignación... Se los dejo a ver si me pueden ayudar!

Private Sub CommandButton3_Click()
'
' Macro6 Macro
'

'
ActiveSheet. Unprotect
Range("F47:G47").Select
ActiveCell.FormulaR1C1 = _
"=COUNTIF(R3C5:R44C5,""Asistencia de izaje a trailers hab."")"
Range("F48:G48").Select
ActiveCell.FormulaR1C1 = _
"=COUNTIF(R3C5:R44C5,""Izaje/montaje de motores - turbinas -Dpto. Turbinas"")"
Range("F49:G49").Select
ActiveCell.FormulaR1C1 = _
"=COUNTIF(R3C5:R44C5,""Asistencia de izaje a coiled tubing en pozo"")"
Range("F50:G50").Select
ActiveCell.FormulaR1C1 = _
"=COUNTIF(R3C5:R44C5,""Asistencia de izaje a slickline en pozo"")"
Range("F51:G51").Select
ActiveCell.FormulaR1C1 = _
"=COUNTIF(R3C5:R44C5,""Asistencia de izaje en paros de planta - trabajos varios"")"
Range("F52:G52").Select
ActiveCell.FormulaR1C1 = _
"=COUNTIF(R3C5:R44C5,""Asistencia de izaje de contigencia"")"

Range("F53:G53").Select
ActiveCell.FormulaR1C1 = _
"=COUNTIF(R3C5:R44C5,""Asistencia de izaje a perforación"")"

Range("F54:G54").Select
ActiveCell.FormulaR1C1 = _
"=COUNTIF(R3C5:R44C5,""Asistencia de izaje a obras civiles"")"
Range("F55:G55").Select
ActiveCell.FormulaR1C1 = _
"=COUNTIF(R3C5:R44C5,""Asistencia a izajes de deposito"")"

Range("F56:G56").Select
ActiveCell.FormulaR1C1 = _
"=COUNTIF(R3C5:R44C5,""Asistencia a izajes separadores-GP"")"
Range("F57:G57").Select
ActiveCell.FormulaR1C1 = _
"=COUNTIF(R3C5:R44C5,""Asistencia de izaje a sector mantenimiento"")"
Range("F58:G58").Select
ActiveCell.FormulaR1C1 = _
"=COUNTIF(R3C5:R44C5,""Asistencia de izaje en general a sector GP"")"

Range("F59:G59").Select
ActiveCell.FormulaR1C1 = _
"=COUNTIF(R3C5:R44C5,""Asistencia de izaje en general a sector TN"")"
Range("F60:G60").Select
ActiveCell.FormulaR1C1 = _
"=COUNTIF(R3C5:R44C5,""Asistencia de izaje en general a pozo"")"

Range("E47").Select
ActiveCell.FormulaR1C1 = _
"=IF(R47C6,""Asistencia de izaje a trailers hab."",""NO HAY COINCIDENCIAS"")"
Range("E48").Select
ActiveCell.FormulaR1C1 = _
"=IF(R48C6,""Izaje/montaje de motores - turbinas -Dpto. Turbinas"",""NO HAY COINCIDENCIAS"")"
Range("E49").Select
ActiveCell.FormulaR1C1 = _
"=IF(R49C6,""Asistencia de izaje a coiled tubing en pozo"",""NO HAY COINCIDENCIAS"")"
Range("E50").Select
ActiveCell.FormulaR1C1 = _
"=IF(R50c6,""Asistencia de izaje a slickline en pozo"",""NO HAY COINCIDENCIAS"")"
Range("E51").Select
ActiveCell.FormulaR1C1 = _
"=IF(R51C6,""Asistencia de izaje en paros de planta - trabajos varios"",""NO HAY COINCIDENCIAS"")"
Range("E52").Select
ActiveCell.FormulaR1C1 = _
"=IF(R52C6,""Asistencia de izaje de contigencia"",""NO HAY COINCIDENCIAS"")"

Range("E53").Select
ActiveCell.FormulaR1C1 = _
"=IF(R53C6,""Asistencia de izaje a perforación"",""NO HAY COINCIDENCIAS"")"

Range("E54").Select
ActiveCell.FormulaR1C1 = _
"=IF(R54c6,""Asistencia de izaje a obras civiles"",""NO HAY COINCIDENCIAS"")"
Range("E55").Select
ActiveCell.FormulaR1C1 = _
"=IF(R55C6,""Asistencia a izajes de deposito"",""NO HAY COINCIDENCIAS"")"

Range("E56").Select
ActiveCell.FormulaR1C1 = _
"=IF(R56C6,""Asistencia a izajes separadores-GP"",""NO HAY COINCIDENCIAS"")"
Range("E57").Select
ActiveCell.FormulaR1C1 = _
"=IF(R57C6,""Asistencia de izaje a sector mantenimiento"",""NO HAY COINCIDENCIAS"")"
Range("E58").Select
ActiveCell.FormulaR1C1 = _
"=IF(R58C6,""Asistencia de izaje en general a sector GP"",""NO HAY COINCIDENCIAS"")"
Range("E59").Select
ActiveCell.FormulaR1C1 = _
"=IF(R59C6,""Asistencia de izaje en general a sector TN"",""NO HAY COINCIDENCIAS"")"
Range("E60").Select
ActiveCell.FormulaR1C1 = _
"=IF(R60C6,""Asistencia de izaje en general a pozo"",""NO HAY COINCIDENCIAS"")"
Range("E47:G60").FormulaHidden = True
ActiveSheet.Protect DrawingObjects:=True, Contents:=True, Scenarios:=True
End Sub

2 respuestas

Respuesta
1

Bueno en Excel no necesitas seleccionar una celda para luego poner algo.

Por ejemplo, decir

Range("A1").Select
ActiveCell.Value = "Cualquier cosa"

no es necesario seleccionar la celda y luego ponerle el valor o la formula, puedes hacerlo directamente, así

Range("A1").Value = "Cualquier cosa"

Tambien podrías, en lugar de usar FormulaR1C1, usar WorksheetFunction de esa manera la validación se hace en el código y solo pasas el resultado (a menos que quieras almacenar la formula en la celda sí o sí)

A mi me parece mejor hacer la evaluación en el código y pasar el resultado, que pasar la formula y hacer la evaluación en la celda, ¿por qué entonces cual seria el punto de usar VBA?

¡Gracias! Me quedo claro, pero de que manera puedo seleccionar el rango F47:¿G60 para aplicar todos lo condicionales que quiero? Fíjate que yo lo hice muy amateur... la idea es porque la tuve la ampliar y se me desplazó todo...

¿Necesitas aplicar la fórmula a todas las celdas del rango? Por ejemplo en tu código tienes esto:

Range("F47:G47").Select
ActiveCell.FormulaR1C1 = "=COUNTIF(R3C5:R44C5,""Asistencia de izaje a trailers hab."")"

En Excel, puedes seleccionar varias celdas a la vez, pero "Activa" solo puede haber una. Con ese código estas seleccionando dos celdas, F47 y G47 pero de las dos, solo una puede ser la celda activa, por defecto es la primera celda del rango, de izquierda a derecha y de arriba abajo, osea F47.

Así que al decirle ActiveCell. Blablabla... esa palabra Active esta refiriéndose solamente a F47 por lo que la fórmula solo se aplicara a esa celda. Y por ende decir antes Range("F47:G47").Select no tiene mucho sentido.

Ahora bien, si lo que quieres es aplicar la fórmula para las dos celdas, entonces, como te había dicho antes, debes aplicarlas directamente al objeto Range sin selección previa, así:

Range("F47:G47").FormulaR1C1 = "=COUNTIF(R3C5:R44C5,""Asistencia de izaje a trailers hab."")"

¡Muchas Gracias! Genial Andy! Y como puedo hacer para emplear una fórmula que valide en el código con worsheetfunction (que no se como usarlo) y también tengan varias condicionales es decir reunir todas la condicionales en una función única (por ejemplo R3C5:R44C5; ""Asistencia de izaje a trailers hab."",,""Asistencia de izaje en general a sector TN""; ""Asistencia de izaje a sector mantenimiento"" etc)... te lo voy a agradecer mucho

Bueno hasta donde puedo interpretar, tu quieres saber cuantas veces se repiten esas "frases" en el rango E3 a E45 (E3C5:R44C5) por cierto, ¿por qué usas ese formato?

Y quieres poner en cada fila el resultado para cada frase.

Luego en la parte de abajo del código me pierdo y no estoy seguro que deseas hacer.

Si me explicas cual es tu objetivo final en esa hoja, talvez pueda ayudarte a elaborar el código correcto porque viendo tu código tengo una idea, pero no estoy muy seguro de lo que quieres hacer.

Y la manera de usar WorksheetFuncion es la siguiente:

Application. WorksheetFunction. CountIf(Argumento 1: rango, Argumento 2: criterio)

Pero no me gusta usar CountIf en este caso... Usaría Evaluate. Dime que quieres hacer y te hago un código y si puedes muestra una imagen de tu hoja

Andy, como lo puse en el asunto soy muy amateur en esto, la idea aprender y mejorar. El código VBA debería leer de ese rango R3C5:R44C5 la cantidad de veces que se repite cualquiera de los términos ""Asistencia de izaje a trailers hab."",,""Asistencia de izaje en general a sector TN""; ""Asistencia de izaje a sector mantenimiento"" etc) y poner el valor de las veces que se repitió cada termino en las filas del rango F47:G60...

Respecto al formato que uso (R3C5:R44C5), la verdad es el que se usar por ahora... pero si hay otra forma mejor para mi y quiero aprender a programar porque soy muy malo en esto...

Mas info Andy!!

BENDICIONES!!!

Ese formato R3C5:R44C5 significa E3:E44

E3:E44 (Columna E fila 3 : Columna E fila 44)

R3C5:R44C5 (Fila 3 Columna 5(E) : Fila 44 Columna 5(E))

El otro es mas facil de leer.

Dame unos minutos para diseñar un procedimiento que haga lo que quieres y te respondo en un rato con el código.

Prueba este código:

Private Sub CommandButton3_Click()
Dim i As Integer
Dim Str1 As String: Str1 = "Asistencia de izaje a trailers hab"
Dim Str2 As String: Str2 = "Izaje/montaje de motores - turbinas -Dpto. Turbinas"
Dim Str3 As String: Str3 = "Asistencia de izaje a coiled tubing en pozo"
Dim Str4 As String: Str4 = "Asistencia de izaje a slickline en pozo"
Dim Str5 As String: Str5 = "Asistencia de izaje en paros de planta - trabajos varios"
Dim Str6 As String: Str6 = "Asistencia de izaje de contigencia"
Dim Str7 As String: Str7 = "Asistencia de izaje a perforación"
Dim Str8 As String: Str8 = "Asistencia de izaje a obras civiles"
Dim Str9 As String: Str9 = "Asistencia a izajes de deposito"
Dim Str10 As String: Str10 = "Asistencia a izajes separadores-GP"
Dim Str11 As String: Str11 = "Asistencia de izaje a sector mantenimiento"
Dim Str12 As String: Str12 = "Asistencia de izaje en general a sector GP"
Dim Str13 As String: Str13 = "Asistencia de izaje en general a sector TN"
Dim Str14 As String: Str14 = "Asistencia de izaje en general a pozo"
Dim ActualStr As String
Dim StrArr As Variant
StrArr = Array(Str1, Str2, Str3, Str4, Str4, Str6, Str7, Str8, Str9, Str10, Str11, Str12, Str13, Str14)
For i = 47 To 60
    ActualStr = StrArr(i - 47)
    Range(Cells(i, 6), Cells(i, 7)).Value = Application.WorksheetFunction.CountIf(Range("E3:E44"), ActualStr)
Next i
End Sub

Haz una copia a parte de tu libro y prueba el código, para ver si hace lo que necesitas.

¡Gracias Andy muy buen aporte profesional! Ahí lo pruebo y te escribo nuevamente!, pensé que era más fácil ja ja... ahora mi consulta es si el código que hiciste, coloca la cantidad de veces que se repitió el termino en las filas de la columna F47:F60 y el termino en si, es decir si por ejemplo de la evaluación del rango R3C5:R44C5 dio que se verificó 10 veces el término "Asistencia de izaje a trailer hab" el código coloca las veces que se observo en Celdas de la columna F47:F60 (que el valor 10) y el termino en la segunda rango de celda de la columna G47:¿G60 respectivamente? No se si me hice entender pero te dejo una foto de la macro completa;

Y para el caso de que no haya coincidencia de ningún termino, se podría poner en las celdas de la columna G47:¿G60 el termino ""no hay concidencias""?

Desde ya te digo que me ayudaste y enseñaste mucho bendiciones!

Anda perfecto Andy! Lo probé pero necesito también que me ponga el termino que se repitió en las celdas de la columna E47:E60, me explique incorrectamente en mensaje previo...

En caso de que no se verifique ninguna repetición debería colocar en las columnas E47:E60 también el termino "no hay coincidencias"... si se puede no...

La verdad que es muy grande el mundo de programar por VBA... me doy cuenta que soy amateur muy amateur...

Si, así:

Private Sub CommandButton3_Click()
Dim i As Integer
Dim Str1 As String: Str1 = "Asistencia de izaje a trailers hab"
Dim Str2 As String: Str2 = "Izaje/montaje de motores - turbinas -Dpto. Turbinas"
Dim Str3 As String: Str3 = "Asistencia de izaje a coiled tubing en pozo"
Dim Str4 As String: Str4 = "Asistencia de izaje a slickline en pozo"
Dim Str5 As String: Str5 = "Asistencia de izaje en paros de planta - trabajos varios"
Dim Str6 As String: Str6 = "Asistencia de izaje de contigencia"
Dim Str7 As String: Str7 = "Asistencia de izaje a perforación"
Dim Str8 As String: Str8 = "Asistencia de izaje a obras civiles"
Dim Str9 As String: Str9 = "Asistencia a izajes de deposito"
Dim Str10 As String: Str10 = "Asistencia a izajes separadores-GP"
Dim Str11 As String: Str11 = "Asistencia de izaje a sector mantenimiento"
Dim Str12 As String: Str12 = "Asistencia de izaje en general a sector GP"
Dim Str13 As String: Str13 = "Asistencia de izaje en general a sector TN"
Dim Str14 As String: Str14 = "Asistencia de izaje en general a pozo"
Dim ActualStr As String
Dim RepeatQty As Integer
Dim StrArr As Variant
StrArr = Array(Str1, Str2, Str3, Str4, Str4, Str6, Str7, Str8, Str9, Str10, Str11, Str12, Str13, Str14)
For i = 47 To 60
    ActualStr = StrArr(i - 47)
    RepeatQty = Application.WorksheetFunction.CountIf(Range("E3:E44"), ActualStr)
    If RepeatQty > 0 Then
        Cells(i, 6).Value = RepeatQty
        Cells(i, 7).Value = ActualStr
    Else
        Cells(i, 6).Value = "No Hay Coincidencia"
        Cells(i, 7).Value = ActualStr
    End If
Next i
End Sub

Andy

No entiendo esto que dices:

En caso de que no se verifique ninguna repetición debería colocar en las columnas E47:E60 también el termino "no hay coincidencias"... si se puede no...

Y en la otra parte cuando no lo encontraba ponia un 0 (cero) que es lo mismo que decir "no hay coincidencia" pero ya te lo cambie para que diga "no hay coincidencia" en lugar de 0

¡Gracias!

Perfecto Andy, refiero a que en las celdas de la columna E47:E60 se coloquen las correspondencias es decir asi;

A ver, prueba así:

Private Sub CommandButton3_Click()
Dim i As Integer
Dim Str1 As String: Str1 = "Asistencia de izaje a trailers hab"
Dim Str2 As String: Str2 = "Izaje/montaje de motores - turbinas -Dpto. Turbinas"
Dim Str3 As String: Str3 = "Asistencia de izaje a coiled tubing en pozo"
Dim Str4 As String: Str4 = "Asistencia de izaje a slickline en pozo"
Dim Str5 As String: Str5 = "Asistencia de izaje en paros de planta - trabajos varios"
Dim Str6 As String: Str6 = "Asistencia de izaje de contigencia"
Dim Str7 As String: Str7 = "Asistencia de izaje a perforación"
Dim Str8 As String: Str8 = "Asistencia de izaje a obras civiles"
Dim Str9 As String: Str9 = "Asistencia a izajes de deposito"
Dim Str10 As String: Str10 = "Asistencia a izajes separadores-GP"
Dim Str11 As String: Str11 = "Asistencia de izaje a sector mantenimiento"
Dim Str12 As String: Str12 = "Asistencia de izaje en general a sector GP"
Dim Str13 As String: Str13 = "Asistencia de izaje en general a sector TN"
Dim Str14 As String: Str14 = "Asistencia de izaje en general a pozo"
Dim ActualStr As String
Dim RepeatQty As Integer
Dim StrArr As Variant
StrArr = Array(Str1, Str2, Str3, Str4, Str4, Str6, Str7, Str8, Str9, Str10, Str11, Str12, Str13, Str14)
For i = 47 To 60
    ActualStr = StrArr(i - 47)
    RepeatQty = Application.WorksheetFunction.CountIf(Range("E3:E44"), ActualStr)
    If RepeatQty > 0 Then
        Cells(i, 5).Value = ActualStr
        Cells(i, 6).Value = RepeatQty
        Cells(i, 7).Value = ActualStr
    Else
        Cells(i, 5).Value = "No Hay Coincidencia"
        Cells(i, 6).Value = "No Hay Coincidencia"
        Cells(i, 7).Value = ActualStr
    End If
Next i
End Sub

:P

Anda muy bien Andy pero tira este error que sera????

Oleee que raro, ¿qué decía el mensaje de error?

Perdón, no había visto la otra foto. No sé que decirte sobre ese error. ME parece bastante extraño. Si quieres me compartes tu libro, súbelo a algún drive y lo descargo y lo reviso.

¿Podrías por favor subirlo a otro drive? Como Google, o Dropbox o subirlo a Mega...

Es que Microsoft One Drive borra cosas del libro cuando lo descargas, ni siquiera encontré el código que te hice, y ha bloqueado funciones.

Andy vaaaa muchas gracias!!!!

https://www.mediafire.com/file/vvcfd9g3vb59evb/Indicadores_de_izaje-Marzo-2019.xlsm/file

Me mandaste un libro con el código de James, lo cambié por el mio y funciona perfectamente. A mi no me da error. Como puedes ver a continuación en este vídeo:

Video demo

No se por qué te sale ese error a ti, vuelve a intentarlo.

Si Andy tienes razón, reinicie la computadora lo probé y anda perfecto!

Cualquier tema te escribo devuelta, sos un excelente entendido en esto de programar por VSB...Agradecido con vos!

Vale compa. Yo soy programador, VBA es super facil especialmente porque todo el mundo lo usa de manera procesal y asi es mas facil de entender, veras que lo aprenderas rapido.

Dios te escuche Andy, he aprendido algo pero estoy muy lejos del nivel de un programador, no quiero dejar de preguntar (para aprender) por ejemplo: ¿Si quisiera que un cierto rango de celdas de una columna haga operaciones aritméticas o de condicionales "if" como podría usar la instrucción worksheetfunction u otro para que lo haga dentro del código vsb? Disculpa si te molesto pero el no saber me ofusca...

Te responderé con gusto pero haz una pregunta nueva, que esto se hizo bastante largo ya ja ja elabora una nueva pregunta y estaré pendiente para responderte. Cada duda nueva que tengas hazla en una pregunta nueva. Así es más cómodo para los dos y mejor para la comunidad de Todoexpertos :)

Ok Andy enseguida hago la pregunta! Te envío saludos y bendiciones nos hablamos en el próximo tema!😁😁😁😁😁

Respuesta
1

Tu macro puede ser simplificada así, como ves este es el resultado

y esta es la macro solo ocupas un ciclo for y una matriz para poner todas las condiciones que quieras

Sub macro_simplificada()
Set datos = Sheets("hoja1").Range("e3:e44")
Set resultados = Sheets("hoja1").Range("e47:f60")
parametros = Array("""Asistencia de izaje a trailers hab.""", _
"""Izaje/montaje de motores - turbinas -Dpto. Turbinas""", _
"""Asistencia de izaje a coiled tubing en pozo""", _
"""Asistencia de izaje a slickline en pozo""", _
"""Asistencia de izaje en paros de planta - trabajos varios""", _
"""Asistencia de izaje de contigencia""", _
"""Asistencia de izaje a perforación""", _
"""Asistencia de izaje a perforación""", _
"""Asistencia de izaje a obras civiles""", _
"""Asistencia a izajes de deposito""", _
"""Asistencia a izajes separadores-GP""", _
"""Asistencia de izaje a sector mantenimiento""", _
"""Asistencia de izaje en general a sector GP""", _
"""Asistencia de izaje en general a sector TN""", _
"""Asistencia de izaje en general a pozo""")
parametros = Application.Transpose(parametros)
With resultados
    filas = .Rows.Count
    For i = 1 To filas
        .Cells(i * 2).Formula = "=COUNTIF(" & datos.Address & "," & parametros(i, 1) & ")"
        .Cells((i * 2) - 1).Formula = "=IF(" & .Cells(i * 2).Address & "," & parametros(i, 1) & "," & """NO HAY COINCIDENCIAS""" & ")"
    Next i
End With
set datos=nothing: set resultados=nothing
End Sub

¡Gracias James! Este anda muy bien también, pero me tira el error siguiente;

Excelente tu aporte se nota que hay profesionales de esto por esta red!

La macro que estas mostando en la imagen no es mía

Añade tu respuesta

Haz clic para o

Más respuestas relacionadas