"Arreglito" de macro 2

10/11/2007 - 22:01 por Miguel | Informe spam
Héctor Miguel:
Aquí tienes el enlace al archivo:
http://www.badongo.com/file/5086970
Un saludo,
M. Ángel

Preguntas similare

Leer las respuestas

#1 Héctor Miguel
11/11/2007 - 02:11 | Informe spam
hola, Miguel !

... el enlace al archivo: http://www.badongo.com/file/5086970



considerando que en la consulta anterior, el problema quedo (principalmente) en el "re/llenado" de los combos...
voy a (tratar de) explicarte los "comos y por que" persistian algunas "incongruencias" por las diferencias entre:
1) los supuestos (desde este lado del mensaje y conforme a la exposicion de las consultas)
2) las realidades (analizando el archivo descargado con la situacion real -y quizas modificada ?-)

1) de tu consulta original se desprende que el re/llenado de los combos se hace 2 veces:

a) una en el evento '_initialize' -> usando la propiedad "RowSource"

b) otra en el evento '_click' del CommandButton2 -> usando el metodo "AddItem" luego de limpiar los combos
nota en tu post original que no hay separacion de codigo entre el commandbutton2 y el commandbutton2

c) por motivos "obvios", mi sugerencia incluia el llamado al procedimiento "Rellena_Combos" EN AMBOS EVENTOS :-((

2) del archivo descargado se observa que NO existe tal "duplicidad" en el re/lleno de los combos (quien lo iba a adivinar) -???-

3) tal como te comentaba en el punto 3 de mi ultima participacion a tu consulta anterior:
"(p.e.) no se porque rellenas los combos unas veces con la propiedad RowSource y otras por el metodo AddItem -?-"
"ni porque usas (WorksheetFunction.CountA) en cada columna (A a F) como si hubiera diferente numero de elementos por columna"

a) del mismo archivo descargado se obtiene que los diferentes elementos por columna (A a F) en la hoja "listas"
(efectivamente) cada columna tiene diferente numero de elementos

b) no parece ser que vayan a ser listados "dinamicos" (o de/crecientes) sino mas bien "estaticos" (entonces)...
por que hacer vaciados y re/llenados de los combos (tanto en el evento de inicio como en cualquiera otro) -???-

c) te sugiero definir nombres para cada rango/columna de tu hoja "listas" y ponerlos como origen (propiedad "RowSource")
-> (incluso) desde en tiempo de diseno de tu formulario
-> y cuando necesites "limpiar" los combos, simplemente estableces su propiedad "ListIndex" en menos 1 (-1)
lo que significa "ningun elemento seleccionado" (y con lo que adelgazas -y bastante- todo tu codigo)

4) creo que hay otro "detallito por ahi" que tiene que ver con el origen de la tabla dinamica (aunque no lo has mencionado) -?-
te sugiero definir un nombre con referencia a rangos dinamicos (o de/crecientes) para el origen de la tabla dinamica

si cualquier duda (o informacion adicional)... comentas ?
saludos,
hector.
Respuesta Responder a este mensaje
#2 Miguel
11/11/2007 - 14:11 | Informe spam
On 11 nov, 02:11, "Héctor Miguel"
wrote:
hola, Miguel !

> ... el enlace al archivo:http://www.badongo.com/file/5086970

considerando que en la consulta anterior, el problema quedo (principalmente) en el "re/llenado" de los combos...
voy a (tratar de) explicarte los "comos y por que" persistian algunas "incongruencias" por las diferencias entre:
1) los supuestos (desde este lado del mensaje y conforme a la exposicion de las consultas)
2) las realidades (analizando el archivo descargado con la situacion real -y quizas modificada ?-)

1) de tu consulta original se desprende que el re/llenado de los combos se hace 2 veces:

a) una en el evento '_initialize' -> usando la propiedad "RowSource"

b) otra en el evento '_click' del CommandButton2 -> usando el metodo "AddItem" luego de limpiar los combos
nota en tu post original que no hay separacion de codigo entre el commandbutton2 y el commandbutton2

c) por motivos "obvios", mi sugerencia incluia el llamado al procedimiento "Rellena_Combos" EN AMBOS EVENTOS :-((

2) del archivo descargado se observa que NO existe tal "duplicidad" en el re/lleno de los combos (quien lo iba a adivinar) -???-

3) tal como te comentaba en el punto 3 de mi ultima participacion a tu consulta anterior:
"(p.e.) no se porque rellenas los combos unas veces con la propiedad RowSource y otras por el metodo AddItem -?-"
"ni porque usas (WorksheetFunction.CountA) en cada columna (A a F) como si hubiera diferente numero de elementos por columna"

a) del mismo archivo descargado se obtiene que los diferentes elementos por columna (A a F) en la hoja "listas"
(efectivamente) cada columna tiene diferente numero de elementos

b) no parece ser que vayan a ser listados "dinamicos" (o de/crecientes) sino mas bien "estaticos" (entonces)...
por que hacer vaciados y re/llenados de los combos (tanto en el evento de inicio como en cualquiera otro) -???-

c) te sugiero definir nombres para cada rango/columna de tu hoja "listas" y ponerlos como origen (propiedad "RowSource")
-> (incluso) desde en tiempo de diseno de tu formulario
-> y cuando necesites "limpiar" los combos, simplemente estableces su propiedad "ListIndex" en menos 1 (-1)
lo que significa "ningun elemento seleccionado" (y con lo que adelgazas -y bastante- todo tu codigo)

4) creo que hay otro "detallito por ahi" que tiene que ver con el origen de la tabla dinamica (aunque no lo has mencionado) -?-
te sugiero definir un nombre con referencia a rangos dinamicos (o de/crecientes) para el origen de la tabla dinamica

si cualquier duda (o informacion adicional)... comentas ?
saludos,
hector.



De nuevo, reiterarte mi agradecimiento por tu ampla contestación; pero
entre tanto post de ida vuelta ya estoy un poco perdido. Entiendo, por
tu respuesta, que las modificaciones a mi código original que me
enviaste en tu anterior respuesta, ya no son de aplicación; puesto
que, como ya te comenté, daba algunos errores. Lo que te pediría,
abusando de de tu paciencia y conocimientos, si a bien lo tienes, es
que adaptes, mediante código, el archivo remitido, con estos últimos
consejos. Y ya, si lo estimas conveniente y no te cuesta mucho, dentro
del código, una frase explicativa de los que haces con cada sentencia.
De esta manera, veré el porqué de las ejecuciones y sin lugar a dudas,
aprenderé mucho más que leyendo varios tutoriales.
En cualquier caso y mientras tanto, me pongo a trastear con tus
consejos y agradecerte, una vez más, tu ayuda totalmente
desinteresada, dedicando tu tiempo y mucho, a explicar a novatos como
yo estos temas.
Un fuerte abrazo y muchas gracias.
M. Ángel
Respuesta Responder a este mensaje
#3 Héctor Miguel
12/11/2007 - 05:26 | Informe spam
hola, Miguel !

... entre tanto post de ida vuelta ya estoy un poco perdido.
Entiendo... que las modificaciones a mi codigo... en tu anterior respuesta, ya no son de aplicacion
... te pediria... que adaptes... codigo... archivo remitido, con estos ultimos consejos
... y... una frase explicativa de los que haces con cada sentencia.
... mientras tanto, me pongo a trastear con tus consejos ...



despues de una "mediana revision" para el uso entendido del formulario y del archivo en si mismo
(y que espero no andar en mis suposiciones "demasiado" lejos de su objetivo) :D te comento:

1) el archivo remitido llega con vinculos (perdidos) a otros libros y nombres con referencias "eliminadas"
(entre otros detalles) por lo que creo que no te sera de utilidad si te lo re-envio con (mis) "correcciones" :-((

2) al final de cuentas, ya no me queda claro si la intencion de no mostrar las hojas (como "listas") es (o no) relevante -?-
ya que en algunos eventos ('_open') ocultas unas pero con el 'Sub Auto_Open' las vuelves a mostrar -?-
ademas de que de todas maneras tienes botones de opcion para "navegar" por las hojas que se requeria ocultar :-((
OJO: en mis pruebas mantuve TODAS las hojas en su estado "visible"
(esta parte de los codigos la dejo a tu mejor criterio o necesidad) :))
OJO tambien con las otras lineas donde te la pasas des/re/ocultando las hojas (prueba mantenerlas todas visibles)

3) segun pruebas realizadas con el archivo remitido, con los siguientes cambios en pocos eventos logras el objetivo:
(solo aclararte que de preferencia se deberan nombrar los rangos de filas variables de las columnas A:F de la hoja "listas")
(y "de pasadita" comentar que estabas administrando erroneamente la seleccion de fecha en el DTPicker1 <= OJO)

si cualquier duda (o informacion adicional)... comentas ?
saludos,
hector.

a) declarar la variable "n" al inicio del modulo del formulario (para su uso en cualquier procedimiento del mismo)
Dim n As Integer

b) modificar el codigo del evento '_click' del boton de registrar (el commandbutton1) a lo siguiente:
Private Sub CommandButton1_Click()
Dim Salir As Boolean
For n = 1 To 2: If Me.Controls("textbox" & n) = "" Then Salir = True: GoTo Verifica
Next
For n = 1 To 9: If Me.Controls("combobox" & n) = "" Then Salir = True: GoTo Verifica
Next
If IsNull(DTPicker1) Then Salir = True
Verifica:
If Salir Then MsgBox "Faltan cosillas por llenar !!!": Exit Sub
With Worksheets("estadistica")
With .Range("a65536").End(xlUp).Offset(1)
.Value = .Row - 6
Range("registro") = .Value + 1
.Offset(, 1) = ComboBox1
.Offset(, 2) = TextBox1.Value
.Offset(, 3) = DTPicker1
.Offset(, 4) = TextBox2
For n = 2 To 14: .Offset(, n + 3) = Controls("combobox" & n): Next
.Offset(, 18) = TextBox3.Value
.Offset(, 19) = TextBox4.Value
.Offset(, 20) = ComboBox15
.Offset(, 21) = TextBox5
End With
End With
End Sub

c) modificar el codigo del evento '_click' del boton de cancelar (el commandbutton2) a lo siguiente:
Private Sub CommandButton2_Click()
DTPicker1 = Null
For n = 1 To 5: Me.Controls("textbox" & n) = "": Next
For n = 1 To 15: Me.Controls("combobox" & n).ListIndex = -1: Next
' Worksheets("listas").Visible = True
' Worksheets("listas").Select
' Worksheets("listas").Visible = False
Worksheets("formulario").Select
End Sub

d) para el evento '_initialize' Y SOLAMENTE si decides no asignar los nombres de rango a los combos...
-> desde en tiempo de diseno vinculandolos con las columnas A:F de la hoja "listas"...
Private Sub UserForm_Initialize()
Rellena_Combos
' Sheets("inicio").Visible = True
' Sheets("listas").Visible = False
' Sheets("tabla").Visible = False
' Sheets("estadistica").Visible = False
' Sheets("gráfico1").Visible = False
Sheets("formulario").Select
End Sub

e) para el "renovado" procedimiento que asigna los nombre de los rangos (A:F de "listas") a los combos:
Private Sub Rellena_Combos()
ComboBox1.RowSource = "uni"
For n = 4 To 8 Step 2: Me.Controls("combobox" & n).RowSource = "doc": Next
For n = 3 To 9 Step 2: Me.Controls("combobox" & n).RowSource = "nac": Next
ComboBox2.RowSource = "mot"
For n = 10 To 14: Me.Controls("combobox" & n).RowSource = "efe": Next
ComboBox15.RowSource = "jui"
End Sub

f) finalmente Y REVISA LOS NOMBRES utilizados en el ejemplo por si se conflictuan con otros existentes en tu libro...
el siguiente procedimiento ELIMINA los nombres (supuestos) y los vuelve a asignar (si hubiera modificaciones "al vuelo")
y se ejecuta desde la mismisima hoja "listas"...
Sub Nombre_a_listas()
Dim nCol As Byte, Listados As Range, n As Byte, TitulosA, TitulosB
TitulosA = Array("Uni", "Doc", "Nac", "Mot", "Efe", "Jui")
TitulosB = Array("Unidad", "Documentos", "Nacionalidad", "Motivo", "Efectos", "JUI")
On Error Resume Next
For n = LBound(TitulosA) To UBound(TitulosA): Names(TitulosA(n)).Delete: Next
On Error GoTo 0
Range("a1:f1") = TitulosA
Set Listados = Range(Cells(1, 1), Cells(1, 1).End(xlDown))
For nCol = 2 To 6
Set Listados = Union(Listados, Range(Cells(1, nCol), Cells(1, nCol).End(xlDown)))
Next
Listados.Select
Selection.CreateNames True
Range("a1:f1") = TitulosB
Range("a1").Select
Set Listados = Nothing
End Sub
Respuesta Responder a este mensaje
#4 Miguel
12/11/2007 - 22:52 | Informe spam
On 12 nov, 05:26, "Héctor Miguel"
wrote:
hola, Miguel !

> ... entre tanto post de ida vuelta ya estoy un poco perdido.
> Entiendo... que las modificaciones a mi codigo... en tu anterior respuesta, ya no son de aplicacion
> ... te pediria... que adaptes... codigo... archivo remitido, con estos ultimos consejos
> ... y... una frase explicativa de los que haces con cada sentencia.
> ... mientras tanto, me pongo a trastear con tus consejos ...

despues de una "mediana revision" para el uso entendido del formulario y del archivo en si mismo
(y que espero no andar en mis suposiciones "demasiado" lejos de su objetivo) :D te comento:

1) el archivo remitido llega con vinculos (perdidos) a otros libros y nombres con referencias "eliminadas"
(entre otros detalles) por lo que creo que no te sera de utilidad si te lo re-envio con (mis) "correcciones" :-((

2) al final de cuentas, ya no me queda claro si la intencion de no mostrar las hojas (como "listas") es (o no) relevante -?-
ya que en algunos eventos ('_open') ocultas unas pero con el 'Sub Auto_Open' las vuelves a mostrar -?-
ademas de que de todas maneras tienes botones de opcion para "navegar" por las hojas que se requeria ocultar :-((
OJO: en mis pruebas mantuve TODAS las hojas en su estado "visible"
(esta parte de los codigos la dejo a tu mejor criterio o necesidad) :))
OJO tambien con las otras lineas donde te la pasas des/re/ocultando las hojas (prueba mantenerlas todas visibles)

3) segun pruebas realizadas con el archivo remitido, con los siguientes cambios en pocos eventos logras el objetivo:
(solo aclararte que de preferencia se deberan nombrar los rangos de filas variables de las columnas A:F de la hoja "listas")
(y "de pasadita" comentar que estabas administrando erroneamente la seleccion de fecha en el DTPicker1 <= OJO)

si cualquier duda (o informacion adicional)... comentas ?
saludos,
hector.

a) declarar la variable "n" al inicio del modulo del formulario (para su uso en cualquier procedimiento del mismo)
Dim n As Integer

b) modificar el codigo del evento '_click' del boton de registrar (el commandbutton1) a lo siguiente:
Private Sub CommandButton1_Click()
Dim Salir As Boolean
For n = 1 To 2: If Me.Controls("textbox" & n) = "" Then Salir = True: GoTo Verifica
Next
For n = 1 To 9: If Me.Controls("combobox" & n) = "" Then Salir = True: GoTo Verifica
Next
If IsNull(DTPicker1) Then Salir = True
Verifica:
If Salir Then MsgBox "Faltan cosillas por llenar !!!": Exit Sub
With Worksheets("estadistica")
With .Range("a65536").End(xlUp).Offset(1)
.Value = .Row - 6
Range("registro") = .Value + 1
.Offset(, 1) = ComboBox1
.Offset(, 2) = TextBox1.Value
.Offset(, 3) = DTPicker1
.Offset(, 4) = TextBox2
For n = 2 To 14: .Offset(, n + 3) = Controls("combobox" & n): Next
.Offset(, 18) = TextBox3.Value
.Offset(, 19) = TextBox4.Value
.Offset(, 20) = ComboBox15
.Offset(, 21) = TextBox5
End With
End With
End Sub

c) modificar el codigo del evento '_click' del boton de cancelar (el commandbutton2) a lo siguiente:
Private Sub CommandButton2_Click()
DTPicker1 = Null
For n = 1 To 5: Me.Controls("textbox" & n) = "": Next
For n = 1 To 15: Me.Controls("combobox" & n).ListIndex = -1: Next
' Worksheets("listas").Visible = True
' Worksheets("listas").Select
' Worksheets("listas").Visible = False
Worksheets("formulario").Select
End Sub

d) para el evento '_initialize' Y SOLAMENTE si decides no asignar los nombres de rango a los combos...
-> desde en tiempo de diseno vinculandolos con las columnas A:F de la hoja "listas"...
Private Sub UserForm_Initialize()
Rellena_Combos
' Sheets("inicio").Visible = True
' Sheets("listas").Visible = False
' Sheets("tabla").Visible = False
' Sheets("estadistica").Visible = False
' Sheets("gráfico1").Visible = False
Sheets("formulario").Select
End Sub

e) para el "renovado" procedimiento que asigna los nombre de los rangos (A:F de "listas") a los combos:
Private Sub Rellena_Combos()
ComboBox1.RowSource = "uni"
For n = 4 To 8 Step 2: Me.Controls("combobox" & n).RowSource = "doc": Next
For n = 3 To 9 Step 2: Me.Controls("combobox" & n).RowSource = "nac": Next
ComboBox2.RowSource = "mot"
For n = 10 To 14: Me.Controls("combobox" & n).RowSource = "efe": Next
ComboBox15.RowSource = "jui"
End Sub

f) finalmente Y REVISA LOS NOMBRES utilizados en el ejemplo por si se conflictuan con otros existentes en tu libro...
el siguiente procedimiento ELIMINA los nombres (supuestos) y los vuelve a asignar (si hubiera modificaciones "al vuelo")
y se ejecuta desde la mismisima hoja "listas"...
Sub Nombre_a_listas()
Dim nCol As Byte, Listados As Range, n As Byte, TitulosA, TitulosB
TitulosA = Array("Uni", "Doc", "Nac", "Mot", "Efe", "Jui")
TitulosB = Array("Unidad", "Documentos", "Nacionalidad", "Motivo", "Efectos", "JUI")
On Error Resume Next
For n = LBound(TitulosA) To UBound(TitulosA): Names(TitulosA(n)).Delete: Next
On Error GoTo 0
Range("a1:f1") = TitulosA
Set Listados = Range(Cells(1, 1), Cells(1, 1).End(xlDown))
For nCol = 2 To 6
Set Listados = Union(Listados, Range(Cells(1, nCol), Cells(1, nCol).End(xlDown)))
Next
Listados.Select
Selection.CreateNames True
Range("a1:f1") = TitulosB
Range("a1").Select
Set Listados = Nothing
End Sub




Hola Héctor,
Una vez más, agradecerte tu rápida contestación e interés. Paso a
exponerte unas dudas, seguramente como consecuencia de mi novated en
el tema:

Con relación al apartado d). Entiendo que si asigno los nombres de rango a los combos, definiendo la propiedad RowSource, en el momento de diseñar el UserForm, no es necesario que incluya este código. ¿Es así, lo suprimo por completo?

Con relación al apartado e). Me asalta la misma duda, ¿si asigno los nombres de rango a los combos, prescindo también de este código?

Con relación al apartado f). Reconozco que este código me tiene intrigado. He realizado varias pruebas y no he averiguado exactamente qué es lo que hace.




No entiendo el por qué de las dos definiciones que das a los elementos
que contienen los listados, por una parte, "Títulos A": "Unidad",
"Documentos", "Nacionalidad", "Motivo", "Efectos", "JUI"; y, por otra,
"Títulos B": "Uni", "Doc", "Nac", "Mot", "Efe", "Jui".
¿Qué quieres decir con modificaciones al vuelo? Que si en la hoja
"Listas", modifico cualquiera de estos Títulos, este código los vuelve
a asignar. Por ejemplo, si cambio en la propia hoja "listas" "mot" por
"Motivo", este código lo modifica y funciona igual? ¿Y si ya he
asignado los nombres de rango a los combos, por medio de la propiedad
RowSource, ¿cómo afecta a este código, es necesario mantenerlo o se
puede suprimir?

Por últmico, en en el punto 4) de un post anterior tuyo, me sugieres definir un nombre con referencia a rangos dinámicos para el origen de la tabla dinámica. Sé definirlo con el asistente de tablas dinámicas, pero no con códigos VBA. ¿Cómo sería?





Muchísimas gracias por tua atención y, sobre todo, por tu paciencia.
M. Ángel
Respuesta Responder a este mensaje
#5 Héctor Miguel
13/11/2007 - 03:55 | Informe spam
hola, Miguel !

d)... Entiendo que si asigno los nombres de rango a los combos, definiendo la propiedad RowSource
en el momento de disenar el UserForm, no es necesario que incluya este codigo. Es asi, lo suprimo por completo?



(asumo que ya debiste hacer la prueba, pero) efectivamente, si los nombres los asignas en el tiempo de diseno
puedes prescindir de todo codigo que solo haga un des/re/llenado de los combos
(en tanto los nombres permanezcan correctamente establecidos, no deberas tener problemas) ;)

e)... si asigno los nombres de rango a los combos, prescindo tambien de este codigo?



efectivamente, y tambien de su "llamada" en el evento '_initialize' del formulario (el des/re/ocultar hojas lo sigo dejando a tu criterio)

f)... este codigo me tiene intrigado... y no he averiguado exactamente que es lo que hace.
No entiendo el por que de las dos definiciones que das a los elementos que contienen los listados... "Títulos A"... "Títulos B": ...



fue solo por hacer (momentaneamente) "cortos" los nombres que se asignan a los rangos y devolverles su descripcion "total"

Que quieres decir con modificaciones al vuelo?
Que si en la hoja "Listas", modifico cualquiera de estos Titulos este codigo los vuelve a asignar.



por modificar al vuelo trate de referirme al caso en el que los elementos de alguna lista (A:F en "listas") aumente o disminuya -?-
con ese codigo puedes volver a establecer el "alcance" de cada listado (hasta cual fila llega cada uno)

Por ejemplo, si cambio en la propia hoja "listas" "mot" por "Motivo", este codigo lo modifica y funciona igual?
Y si ya he asignado los nombres de rango a los combos, por medio de la propiedad RowSource
como afecta a este codigo, es necesario mantenerlo o se puede suprimir?



si piensas aprovechar asignar los nombres a la propiedad "RowSource" desde en tiempo de diseno...
(te sugiero) no hagas cambios a los nombres asignados/establecidos/... "originales" (a cada combo en diseno)
o... necesitaras volver a establecer cada nombre con su cada combo -?-

... en en el punto 4) de un post anterior tuyo
me sugieres definir un nombre con referencia a rangos dinamicos para el origen de la tabla dinamica.
Se definirlo con el asistente de tablas dinamicas, pero no con codigos VBA. Como seria?



no es necesario usar codigo para definir un nombre que haga referencia a rangos dinamicos (o de/crecientes)
1) selecciona la hoja "estadistica" y activa la celda A6 (se asume/entiende que el rango A1:A5 va a contnuar VACIO <= OJO)
2) ve a (menu) isertar / nombre / definir...
asigna un nombre (p.e. BaseTD)
usa la siguiente formula: =desref($a$6,,,contara($a:$a),22)
(ojo con el separador de argumentos, yo uso la coma y... excel se encargara de completar la formula con el nombre de la hoja)
3) despues ve a la hoja con la tabla dinamica, activa alguna celda dentro de la TD y usa al asistente:
"regresa" al paso 2 y en el cuadro de edicion de referencias (en lugar del rango que seleccionas de la hoja estadistica)...
-> introduces el signo '=' seguido por el nombre que hayas asignado (p.e. =basetd)
-> termina el asistente y haz un refresco de la TD ;)

si cualquier duda (o informacion adicional)... comentas ?
saludos,
hector.
Respuesta Responder a este mensaje
Ads by Google
Help Hacer una preguntaSiguiente Respuesta Tengo una respuesta
Search Busqueda sugerida