Sei sulla pagina 1di 37

16:08 23/10/2001 == TRUCOS DE VISUAL BASIC, VBA, API Y REGEDIT == Nota: La mayoria de los trucos son mensajes de la lista

TRAPOS_SUCIOS copiados en este fichero, pero tambien hay trucos nuevos. Se usa el formato .TXT porque no se usan tablas ni imagenes. (Si tienes Windows 95/98, usa el ULTRAEDIT o cualquier otro editor de texto, esto es demasiado para el NOTEPAD) ;-) [Este fichero se ira actualizando cada mes, mas o menos] 01) 02) 03) 04) 05) 06) 07) 08) 09) 10) 11) 12) 13) 14) 15) 16) 17) 18) 19) 20) 21) 22) 23) 24) 25) 26) 27) 28) 29) 30) 31) 32) 33) 34) 35) 36) 37) 38) 39) 40) 41) 42) 43) 44) 45) 46) 47) 48) Copiar todos los nodos de un treeview a otro [recursividad] Pasar de hexadecimal a decimal Pasar de octal a decimal Sacar letra de NIF Degradado para el form Sacar nombre del PC [API] Sacar nombre del Usuario [API] Hacer que el programa espere [API] Lista de Webs de Visual Basic Lista de errores de Visual Basic Impedir que el programa se cargue dos veces Cazar errores con ERL Forma de saber a cuantos niveles de profundidad esta un nodo Cambiar el nombre del PC [API] Mostrar tipos de fichero que reconoce Word [VBA] Forma de saber si una fecha cae en fin de semana Duplica comillas simples (util para SQL) [VB6] Quita acentos en cadenas (util para busquedas) [VB6] Quita acentos en cadenas (util para busquedas) [VB5 y VBA] Duplica comillas simples (util para SQL) [VB5 y VBA] Intercambio de imagenes [para controles Image y PictureBox] Pasar parmetros a ActiveX [desde ASP] Sacar informacin de la hoja de clculo [VBA] Esta el PC conectado a Internet? [API] Mostrar la ventana que Windows usa para elegir un directorio [API] Donde estn 'Mi PC' y otros iconos en el registro [RegEdit] Como saber si se est usando Windows NT o no [API] Usar funciones definidas por usuario en Excel 97 [VBA] Sacar el n de dias entre fechas sin contar fines de semana Comprobar si un item de una coleccion existe Comprueba si todos los item indicados de una coleccin existen Comprobar si una tabla de Access 97 existe [VBA] Lista de errores del VBA de Access 97 [VBA] Como adivinar la password de bases de datos cuando usas ODBC [RegEdit] Desactivar algunas opciones del NT [Regedit] Sub que imita al comando SWAP del Qbasic Formato de celdas de una hoja Excel [VBA] Abrir archivos .HLP en Excel [VBA] Msgbox que se autodestruye [VB] Pruebas con el 'mueco diablico' de Office 97 [VBA] Sacar nombres de tablas y campos en SQL Server y Access 97 [SQL] Usar SPLIT( ) para devolver la extensin de un fichero Separar argumentos pasados a un programa VB [funcin Command( )] Pruebas para insertar texto con Word usando macros [VBA] Insertar un fichero de texto en Word usando macros [VBA] Insertar un trozo de una hoja de clculo en Word usando macros [VBA] Rellenar un grafico de Microsoft Graph desde Visual Basic 6 [VB5 ,VB6] Truco con la propiedad ItemData (Listbox y Combo) [VB5 , VB6]

49) Abrir un fichero de texto sin que salga la ventana 'Convertir archivo' [VBA] ==================================== 01) Copiar todos los nodos de un treeview a otro [recursividad] 'sub recursiva usada para copiar todos los nodos de un treeview a otro Private Sub XCopy_Nodos(nodOrigen As Node, tvwOrigen As TreeView, _ tvwDestino As TreeView, strIndices As String, lngParent As Long) On Error GoTo FATALITYS '// variables usadas en intercambio datos entre nodos Dim lngNum As Long 'indice del nodo (lo saca de strIndices y strIndices_Bak) '// variables usadas en bucles Dim intCont As Integer 'para moverse por los nodos que cuelgan del nodo actu al Dim nodEsclavo As Node 'nodos que cuelgan del nodo actual Static intNivel As Integer '<*> '------------------------------------'<*> Truco: El valor por defecto de las static es un 0. Solo sirve para controlar cuantas veces se llama a si misma la funcion, para evitar errores "Si n espacio en la pila" 'Marca el nodo seleccionado para borrarse (solo lo hace una vez) If (intNivel = 0) Then tvwDestino.Nodes.Clear With tvwOrigen.Nodes(1) tvwDestino.Nodes.Add , , .Key, .Text, .Image, .SelectedImage tvwDestino.Nodes(tvwDestino.Nodes.Count).Tag = .Tag End With End If 'comienza a marcar todo lo que cuelga de este nodo If (nodOrigen.Children > 0) Then For intCont = nodOrigen.Children To 1 Step -1 If (intCont = nodOrigen.Children) Then '<-- uno detras de otro Set nodEsclavo = nodOrigen.Child Else Set nodEsclavo = nodEsclavo.Next End If 'crea el nodo (Add) With nodEsclavo tvwDestino.Nodes.Add .Parent.Key, tvwChild, .Key, .Text, .Image, .Sele ctedImage End With 'aade algunas caracteristicas: negrita, color, .Tag With tvwDestino.Nodes(tvwDestino.Nodes.Count) .Tag = nodEsclavo.Tag .Bold = nodEsclavo.Bold .ForeColor = nodEsclavo.ForeColor End With 'si es NOTHING, pasa de el If (Not nodEsclavo Is Nothing) Then If (nodEsclavo.Children > 0) Then intNivel = intNivel + 1 'se ha metido un nivel mas adentro Call XCopy_Nodos(nodEsclavo, tvwOrigen, tvwDestino, strIndices, ln gParent) 'la sub se llama a si misma intNivel = intNivel - 1 'ha subido un nivel End If End If Next End If 'marca el que tiene un nivel por encima (s/n)

If (intNivel = 0) Then Set nodOrigen = Nothing Set nodEsclavo = Nothing End If Exit Sub FATALITYS: MsgBox Err.Description, , Err.Number & "(Sub XCopy_Nodos [Nivel " & _ intNivel & "])" End Sub ==================================== 02) Pasar de hexadecimal a decimal 'Devuelve "?" si hay un error o se pasa una cadena vacia 'se puede hacer que devuelva un LONG, pero entonces no se sabe si 'hay un error o no fijandose en el valor que devuelve la funcion 'Ejemplo: HexToDec("ACE") Public Function HexToDec(ByVal strHex As String) As String On Error GoTo FATALITY Dim strTemp As String '------------------------strHex = UCase(Trim(strHex)) If (strHex = "") Then HexToDec = "?" Else strTemp = "&H" & strHex 'los ns hex empiezan en &H HexToDec = CStr(CLng(strTemp)) End If On Error Goto 0 'desactiva control de errores Exit Function FATALITY: If (Err.Number = 13) Then Err.Description = "Los caracteres permitidos " & _ "son los numeros 0-9 y las letras A-F" End If MsgBox ("Error " & Err.Number & ": " & Err.Description), _ vbExclamation, "Function HexToDec" HexToDec = "?" End Function ==================================== 03) Pasar de octal a decimal 'Convierte un n octal a uno decimal. 'Se devuelve "?" si el n no sirve (ej: 999) Public Function OctToDec(ByVal strOct As String) As String On Error GoTo FATALITY Dim strTemp As String '------------------------stroct = UCase(Trim(strOct)) If (stroct = "") Then OctToDec = "?" Else strTemp = "&O" & strOct 'los ns en octal empiezan en &O OctToDec = CStr(CLng(strTemp)) End If On Error Goto 0 'desactiva control de errores

Exit Function FATALITY: If (Err.Number = 13) Then Err.Description = "Los caracteres permitidos " & _ "son los numeros 0-7" End If MsgBox ("Error " & Err.Number & ": " & Err.Description), _ vbExclamation, "Function octToDec" OctToDec = "?" End Function ==================================== 04) Sacar letra de NIF '-- constantes -Public Const cteNIF_MAX_CHARS = 9 Public Const cteDNI_MAX_NUMS = 8 Public Const cteDNI_MIN As Long = 0 Public Const cteDNI_MAX As Long = 99999999 '-- caracteres que puede devolver strSacar_NIF() Public Const cteNIF = "TRWAGMYFPDXBNJZSQVHLCKE" 'strSacar_NIF(): Saca la letra del NIF a partir del num de DNI 'Si la cadena no sirve devuelve "" Public Function strSacar_NIF(ByVal strNif As String) As String On Error GoTo Errores_Cazados Dim strTemp As String 'Quita espacios strNif = Trim(strNif) 'Si es una cadena vacia, se ignora... 'Solo se cuentan los 8 primeros caracteres If (Len(strNif) >= cteNIF_MAX_CHARS) Then strNif = Left(strNif, cteNIF_MAX_CHARS - 1) End If 'Si no es una cadena esta vacia, saca la letra del NIF. If (IsNumeric(strNif)) Then 'Quita espacios strNif = Trim(strNif) 'Si el n es demasiado grande o es < 0 se devuelve 'una cadena vacia... If (Len(strNif) > cteDNI_MAX_NUMS) Then strSacar_NIF = "" ElseIf (CLng(strNif) > cteDNI_MAX) Then strSacar_NIF = "" ElseIf (CLng(strNif) < cteDNI_MIN) Then strSacar_NIF = "" Else strSacar_NIF = Mid(cteNIF, _ 1 + (Val(strNif) Mod 23), 1) End If Else strSacar_NIF = "" End If Exit Function Errores_Cazados: MsgBox ("Error " & Err.Number & ": " & Err.Description), _ vbExclamation, "Function strSacar_NIF" End Function

==================================== 05) Degradado para el form 'El color del fondo empieza en azul (o cualquier otro 'color) y acaba en negro (pero si empiezas en negro 'acabas en blanco). Si metes un color que no es una 'de las constantes vbRed, vbYellow,... o cualquier 'otra usada para colores, se usa vbBlue (azul) Public Sub Degradado_Form(frmForm As Form, _ Optional lngColor As ColorConstants = vbBlue) Dim intCont As Integer Dim intNum As Integer Dim lngRGB As Long '-----------------------------------'- scaleheight sirve para no tener que preocuparse por ' la altura del formulario '- si no pones autoredraw a TRUE, la sub no hace nada '- drawsetyle y drawmode se usa con los metodos line, circle,... frmForm.AutoRedraw = True frmForm.DrawStyle = vbInsideSolid frmForm.DrawMode = vbCopyPen frmForm.ScaleMode = vbPixels 'usa pixels, no twips frmForm.DrawWidth = 2 'grosor de linea frmForm.ScaleHeight = 256 '<*> '<*> se mete 256 porque a la funcion RGB() se le pasan ns ' entre 0 y 255 '---For intCont = 0 To ScaleHeight - 1 intNum = (255 - intCont) If (lngColor = vbRed) Then lngRGB = RGB(intNum, 0, 0) 'rojo ElseIf (lngColor = vbGreen) Then lngRGB = RGB(0, intNum, 0) 'verde ElseIf (lngColor = vbBlue) Then lngRGB = RGB(0, 0, intNum) 'azul ElseIf (lngColor = vbYellow) Then lngRGB = RGB(intNum, intNum, 0) 'amarillo ElseIf (lngColor = vbMagenta) Then lngRGB = RGB(intNum, 0, intNum) 'magenta ElseIf (lngColor = vbWhite) Then lngRGB = RGB(intNum, intNum, intNum) 'blanco ElseIf (lngColor = vbCyan) Then lngRGB = RGB(0, intNum, intNum) 'cyan ElseIf (lngColor = vbBlack) Then lngRGB = RGB(intCont, intCont, intCont) 'negro Else lngRGB = RGB(0, 0, intNum) End If frmForm.Line (0, intCont)-(Screen.Width, intCont - 1), lngRGB, B Next '-- deshace los cambios frmForm.AutoRedraw = False frmForm.ScaleMode = vbTwips frmForm.ScaleHeight = frmForm.Height End Sub ==================================== 06) Sacar nombre del PC [API]

'Meter esta funcion API en un modulo (.BAS): Declare Function GetComputerName Lib "kernel32.dll" _ Alias "GetComputerNameA" _ (ByVal lpBuffer As String, nSize As Long) As Long 'strNombre_PC(): Devuelve el nombre del PC (el que se usa al entrar 'en Windows NT (o cualquier otra versin)) Public Function strNombre_PC() 'nombre del PC (se usa en la funcion del API) Dim strPC As String 'Longitud de la cadena (se usa en la funcion del API) Dim lngLongitud As Long 'Valor devuelto por la funcin del API Dim lngRetVal As Long '----------------------------------------------------strPC = Space(255) lngLongitud = 255 'Saca el nombre del PC lngRetVal = GetComputerName(strPC, lngLongitud) strPC = Left(strPC, InStr(strPC, vbNullChar) - 1) strNombre_PC = strPC End Function

==================================== 07) Sacar nombre del Usuario [API] 'Para que esto funcione debes incluir esto en un modulo ' ' Declare Function GetUserName Lib "advapi32.dll" Alias _ ' "GetUserNameA" (ByVal lpBuffer As String, nSize As Long) As Long ' 'strNombre_Usuario(): Devuelve el nombre del usuario (el que se usa al entrar en Windows NT '(o cualquier otra versin)) Public Function strNombre_Usuario() Dim strUsuario As String 'nombre usuario (se usa en la funcion API) Dim lngLongitud As Long 'Longitud de la cadena Dim lngRetVal As Long 'Valor devuelto por la funcin del API '----------------------------------------------------strUsuario = Space(255) lngLongitud = 255 'Saca el nombre del usuario lngRetVal = GetUserName(strUsuario, lngLongitud) strUsuario = Left(strUsuario, InStr(strUsuario, vbNullChar) - 1) strNombre_Usuario = strUsuario End Function ==================================== 08) Hacer que el programa espere [usa API] Se consigue metiendo esta funcion API en un modulo Declare Sub Sleep Lib "kernel32.dll" (ByVal dwMilliseconds As Long) - 'ByVal dwMilliseconds As Long' es el n de milisegundos que espera.

Ejemplo: Private Sub Mover_Imagen(img as Image) Dim intNum as Integer '-----------------------------Randomize Timer intNum = Int(Rnd * 8) + 1 For X = 1 to 100 Select Case (intnum) Case 1: img.Move img.Left + 10, img.Top + 10 'diagonal abajo-dcha Case 2: img.Move img.Left + 10, img.Top - 10 'diagonal arriba-dcha Case 3: img.Move img.Left - 10, img.Top + 10 'diagonal abajo-izq Case 4: img.Move img.Left - 10, img.Top - 10 'diagonal arriba-izq Case 5: img.Move img.Left, (img.Top - 10) 'hacia arriba Case 6: img.Move img.Left, (img.Top + 10) 'hacia abajo Case 7: img.Move (img.Left + 10), img.Top 'hacia la derecha Case 8: img.Move (img.Left - 10), img.Top 'hacia la izquierda End Select Sleep (500) 'espera medio segundo antes de mover otra vez Next End Sub

==================================== 09) Lista de Webs de Visual Basic La mayoria estan en ingles, pero los ejemplos que hay son buenos. [VISUAL BASIC] http://www.vb-helper.com/ http://www.vb-helper.com/wanted.htm http://www.vb-helper.com/HowToAdv.htm http://www.vb-world.net/activex/ http://www.mvps.org/btmtz/ <-- Brad's VB-32 Programs & Samples http://www.vbthunder.com/ <-- VISUAL BASIC THUNDER http://www.msdn.microsoft.com/vbasic/downloads/samples.asp http://www.vbring.com/ <-- Visual Basic Ring http://www.trinitysolution.com/vb/ <-- VB Tips & Tricks http://www.al-williams.com/new/tech.htm <-- mas trucos http://artsoft.al.ru/ <-- como crear un protector de pantalla con VB http://www.vbweb.co.uk/ [API DE WINDOWS] http://guille.costasol.net/vb_api.htm http://www.vb-world.net/api/tips.html <-- ejemplos usando API's http://www.vb-world.net/api/tip146.html <-- start screensaver in code http://www.vb-world.net/api/tip112.html <-- saca RAM libre y usada http://www.vb-world.net/api/tip99.html <-- comprobar si tienes CD http://www.vb-world.net/api/tip38.html <-- muestra/oculta taskbar http://www.vb-world.net/api/tip83.html <-- aadir 'Acerca de' al menu de control [API DE WINDOWS II]

http://www.mvps.org/vb/index2.html?apixref.htm http://www.vbapi.com/ref/index.html <--- Windows API Reference http://artsoft.agava.ru/winapi1.htm <-- (el n puede ser 1-3) [API DE WINDOWS III (UNDOCUMENTED APIS)] http://support.microsoft.com/support/kb/articles/q187/6/74.asp <-- como encontrar ctes indocumentadas http://www.geocities.com/SiliconValley/4942/index.html <-- Undocumented Functions Windows 95 http://www.sonic.net/~undoc/ http://www.undoc.com/ http://community.borland.com/article/0,1410,20177,00.html [CONTROLES ACTIVEX] http://orbita.starmedia.com/~miros/controle.htm http://www.internals.com/utilities/utilities.htm <-- tiene APISPY32 http://www.mvps.org/ccrp/ <-- CCRP: Common Controls Replacement Project. (gratis ) :) http://www.ariad-software.com/products/activex/xtools/button.htm <-CommandButtonX 5.0 (como el commandbutton, pero la imagen puede ponerse en cualquier parte) http://www.sevillaonline.com/ActiveX/ http://newapps.internet.com/appstopics/Win_95_Visual_Basic_Components.html http://winfiles.cnet.com/apps/98/vb-comp-q.html http://www.vbaccelerator.com <-- iconos en menus http://www.vbaccelerator.com/overctl.htm <-- varios activex http://www.designercontrols.com/ImgX/ http://www.webreference.com/programming/activex.html http://development.freeservers.com/ http://www.softseek.com/Programming/ActiveX/ http://www.davecentral.com/imgvact.html http://www.programfiles.com/index.asp?menu2=32 http://www.hallogram.com/agchoicetoolkit/ ==================================== 10) Lista de errores de Visual Basic Los ns que no aparecen son: 'Error definido por la aplicacin o el objeto' 00000 -- [Sin errores] 00003 -- Return sin GoSub 00005 -- Llamada a procedimiento o argumento no vlidos 00006 -- Desbordamiento (overflow) 00007 -- Memoria insuficiente 00009 -- El subndice est fuera del intervalo 00010 -- La matriz est fija o temporalmente bloqueada 00011 -- Divisin por cero 00013 -- No coinciden los tipos 00014 -- Espacio para cadenas insuficiente 00016 -- Expresin demasiado compleja 00017 -- No se puede realizar la operacin solicitada 00018 -- Interrupcin por parte del usuario 00020 -- Resume sin error 00028 -- Espacio de pila insuficiente 00035 -- Procedimiento Sub o Function no definido 00047 -- Hay demasiados clientes de la aplicacin DLL 00048 -- Error al cargar la biblioteca DLL 00049 -- La convencin de llamadas a DLL es incorrecta 00051 -- Error interno 00052 -- Nombre o nmero de archivo incorrecto

00053 -- No se ha encontrado el archivo 00054 -- Modo de archivo incorrecto 00055 -- El archivo ya est abierto 00057 -- Error de E/S de dispositivo 00058 -- El archivo ya existe 00059 -- Longitud de registro incorrecta 00061 -- Disco lleno 00062 -- La entrada de datos ha sobrepasado el final del archivo 00063 -- Nmero de registro incorrecto 00067 -- Hay demasiados archivos 00068 -- El dispositivo no est disponible 00070 -- Permiso denegado 00071 -- Disco no preparado 00074 -- No se puede cambiar el nombre con una unidad de disco diferente 00075 -- Error de acceso a ruta o archivo 00076 -- No se ha encontrado la ruta de acceso 00091 -- Variable de tipo Object o la variable de bloque With no est establecida 00092 -- El bucle For no est inicializado 00093 -- La cadena modelo no es vlida 00094 -- Uso no vlido de Null 00096 -- No se pueden desactivar eventos de objeto porque el objeto ya desencade na el nmero mximo de eventos que admite 00097 -- No se puede llamar a una funcin friend de un objeto que no sea una insta ncia de una clase 00098 -- Una llamada a una propiedad o un mtodo no puede incluir una referencia a un objeto privado como un argumento o un valor de retorno 00321 -- Formato de archivo no vlido 00322 -- No se puede crear un archivo temporal necesario 00325 -- Formato no vlido en el archivo de recursos 00380 -- El valor de la propiedad no es vlido 00381 -- El ndice de la matriz de propiedades no es vlido 00382 -- No se admite Set en tiempo de ejecucin 00383 -- No se admite Set (propiedad de slo lectura) 00385 -- Se necesita un ndice de matriz de propiedades 00387 -- Set no est permitido 00393 -- No se admite Get en tiempo de ejecucin 00394 -- No se admite Get (propiedad de slo escritura) 00422 -- No se encontr la propiedad 00423 -- No se ha encontrado la propiedad o el mtodo 00424 -- Se requiere un objeto 00429 -- El componente ActiveX no puede crear el objeto 00430 -- Esta clase no admite Automatizacin o no admite la interfaz esperada 00432 -- No se encontr el nombre del archivo o de la clase durante la operacin de Automatizacin 00438 -- El objeto no admite esta propiedad o mtodo 00440 -- Error de Automatizacin 00442 -- Se ha perdido la conexin con la biblioteca de tipos o con la biblioteca de objetos para proceso remoto. Haga clic en Aceptar para quitar la referencia. 00443 -- El objeto de Automatizacin no tiene un valor predeterminado 00445 -- El objeto no admite esta accin 00446 -- El objeto no admite argumentos con nombre 00447 -- El objeto no admite la configuracin regional actual 00448 -- No se ha encontrado el argumento con nombre 00449 -- El argumento no es opcional 00450 -- Nmero de argumentos errneo o asignacin de propiedad no vlida 00451 -- El procedimiento Let de la propiedad no est definido y el procedimiento Get no ha devuelto un objeto 00452 -- Nmero ordinal no vlido 00453 -- No se encuentra la funcin de biblioteca DLL especificada 00454 -- No se encuentra el recurso de cdigo

00455 00457 00458 00459 00460 00461 00462 00463 00481 00482 00735 00744 00746

--------------

Error en el bloqueo de los recursos de cdigo Esta clave ya est asociada a un elemento de esta coleccin La variable usa un tipo de Automatizacin no admitido en Visual Basic El objeto o la clase no admite el conjunto de eventos El formato del Portapapeles no es vlido No se encontr el mtodo o el miembro de datos El equipo servidor remoto no existe o no est disponible La clase no est registrada en el equipo local La imagen no es vlida Error de impresora No se puede guardar el archivo en TEMP No se encontr el texto de bsqueda Reemplazamientos demasiado largos

==================================== 11) Impedir que el programa se cargue dos veces 'Nota: para que esto funcione hay que meterse en la ultima opcion del 'menu PROYECTO, ir a 'Objeto inicial' y elegir 'SUB MAIN' ' 'Esta sub debe estar dentro de un mdulo ' '// impide que el programa se cargue dos veces en el mismo PC Private Sub Main If (App.PrevInstance) Then MsgBox "Este programa no puede ejecutarse " & vbCrlf & _ "dos veces en el mismo PC", vbCritical, "ERROR" End Else frmPrincipal.Show 'carga y muestra el formulario frmPrincipal End If End Sub

==================================== 12) Cazar errores con ERL Una forma de cazar errores es numerar las lineas de la Sub / Function que esta dando problemas y usar la funcion Erl (esta funcin devuelve el n de linea en que se produce el error). Este truco sirve en Qbasic y sigue funcionando en Visual Basic, aunque en la MSDN ni la nombren. Nota: No es necesario que los numeros de linea sean consecutivos (es mas practico ponerlos de 10 en 10) ni que esten ordenados. Ejemplo: Private Sub Leer_Fichero(strFich As String) Dim strMemo As String Dim strLinea As String ''-------------------------------------On Error GoTo Fatalitys 1 Open strFich For Input As #3 'abre para leer. Aqui puede dar errores. 2 Do Until EOF(3) 'hasta que llegue al final del fichero 3 Line Input #3, strLinea 'lee una linea del fichero 4 If (strMemo <> "") Then strMemo = strMemo & vbCrLf 'mete salto linea 5 strMemo = strMemo & strLinea 6 Loop 7 Close #3

8 Label3.Caption = strMemo 'muestra el contenido del fichero Exit Sub Fatalitys: MsgBox "Linea " & Erl & " -- " & "Error " & Err.Number & vbCrLf & _ Err.Description, vbOKOnly, "Error" End Sub Con esa Messagebox te sale algo parecido a esto : Linea 1 -- Error 53 No se ha encontrado el archivo ==================================== 13) Forma de saber a cuantos niveles de profundidad esta un nodo '-- Si el nodo que se pasa a la funcion es el nodo raiz (se sabe pq la propiedad Parent de ese nodo es Nothing), la funcion devuelve 0 '-- Si se pasa NOTHING, la funcion devuelve -1 '-- Si se pasa cualquier otro nodo, la funcin devuelve un n > 0 Public Function Get_Profundidad_Nodo(nod As Node) As Integer On Error GoTo FATALITYS Dim nodBackup As Node Dim intNivel As Integer '--------------------------If (nod Is Nothing) Then Get_Profundidad_Nodo = -1 Exit Function End If 'si llega aqui es pq no se paso un NOTHING Set nodBackup = nod intNivel = 0 Do Until (nodBackup.Parent Is Nothing) intNivel = intNivel + 1 Set nodBackup = nodBackup.Parent 'sube un nivel Loop Get_Profundidad_Nodo = intNivel Exit Function FATALITYS: MsgBox Err.Description, , Err.Number & " (Function Get_Profundidad_Nodo)" End Function ==================================== 14) Cambiar el nombre del PC [API] 'Meter esta funcion en un modulo Declare Function SetComputerName Lib "kernel32" _ Alias "SetComputerNameA" (ByVal lpComputerName As String) As Long 'Para que esto funcione crea un formulario con una textbox (se debe 'llamar txtNombrePC) y dos botones (cmdOK y cmdCancelar). Despues 'puedes poner todo lo que te parezca. ;) 'Cambia el nombre y sale Private Sub cmdOK_Click() SetComputerName txtNombrePC.Text & vbNullChar '<*> '<*> Hay que incluir el caracter NULL (ASCII 0) al final Unload Me End Sub

'Sale sin cambiar el nombre Private Sub cmdCancelar_Click() Unload Me End Sub ==================================== 15) Mostrar tipos de fichero que reconoce Word [VBA] 'show_conv(): Mostrar tipos de fichero que reconoce Word 'esto depende de las opciones usadas en la instalacion de Word Sub Show_Conv() Dim conv As FileConverter Dim nfo As String '------------------------------------For Each conv In FileConverters nfo = nfo & conv.ClassName & " ===> " & conv.FormatName & vbCrLf Next conv MsgBox nfo, vbOKOnly + vbInformation, "CLASSNAME ==> PROGRAMA" End Sub ==================================== 16) Forma de saber si una fecha cae en fin de semana 'devuelve TRUE si la fecha es fin de semana Private Function blnFinDeSemana(ByVal dtFecha As Date) As Boolean 'Format(dtFecha, "w", vbMonday, vbFirstJan1) da un n 1-7 '1=lunes, 2=martes, ... , 7=domingo If (Format(dtFecha, "w", vbMonday, vbFirstJan1) < 6) Then blnFinDeSemana = False Else blnFinDeSemana = True End If End Function ==================================== 17) Duplica comillas simples (util para SQL) 'Duplica las comillas simples en una cadena. 'Ejemplo: ' SQL = "SELECT * FROM COCHES " & vbcrlf & _ ' " WHERE PILOTO = '" & Duplicar_Comillas(txtPiloto.Text) & "'" ' Public Function Duplicar_Comillas(ByVal strMemo as String) as String Duplicar_Comillas = Replace(strMemo, "'", "''") End Function ==================================== 18) Quita acentos en cadenas (util para busquedas) [VB 6] 'constantes usadas por la funcion de quitar acentos 'Si estan en un modulo deben ser 'Public Const' Const cteCON_ACENTOS = "" Const cteSIN_ACENTOS = "aaaaAAAAeeeeEEEEiiiiIIIIooooOOOOuuuuUUUUyyY" 'Esta funcion puede ser util cuando se busca por campos caracter en

'una tabla... 'Ej: ? Quitar_Acentos("Rubn") ---> "Ruben" Public Function Quitar_Acentos(ByVal strNombre As String) As String Dim intCont As Integer '-------------------------------For intCont = Len(cteCON_ACENTOS) To 1 Step -1 strNombre = Replace(strNombre, Mid(cteCON_ACENTOS, intCont, 1), _ Mid(cteSIN_ACENTOS, intCont, 1)) Next Quitar_Acentos = strNombre End Function

==================================== 19) Quita acentos en cadenas (util para busquedas) [VB 5 y VBA] '---------Const cteSIN_ACENTOS = "aaaaAAAAeeeeEEEEiiiiIIIIooooOOOOuuuuUUUUyyY" Const cteCON_ACENTOS = "" '---------' La funcion Replace() no existe en Visual Basic 5.0 o anteriores y ' tampoco en el VBA de Excel, Word,... Asi que para los que no vayais ' a usar Visual Basic 6 (o el 7 cuando aparezca), tendreis que usar ' esta otra: Private Function strQuitar_Acentos(ByVal strMemo As String) As String Dim intCont As Integer Dim intPos As Integer '----------------------------------For intCont = 1 To Len(cteCON_ACENTOS) 'si encuentra uno de los caracteres de cteCON_ACENTOS, empieza a 'buscar y cambiar If InStr(1, strMemo, Mid(cteCON_ACENTOS, intCont, 1)) Then intPos = InStr(1, strMemo, Mid(cteCON_ACENTOS, intCont, 1)) Do Until (intPos = 0) 'strmemo=(los que hay antes)+(car. sin acento)+(los que hay despues) strMemo = Left(strMemo, intPos - 1) & Mid(cteSIN_ACENTOS, intCont, 1) & _ Mid(strMemo, intPos + 1) 'busca el siguiente (0 si no lo encuentra) intPos = InStr(intPos, strMemo, Mid(cteCON_ACENTOS, intCont, 1)) Loop End If Next strQuitar_Acentos = strMemo End Function

==================================== 20) Duplica comillas simples (util para SQL) [VB 5 y VBA] 'Duplica comillas simples de una cadena. Para quitarse de problemas 'al crear INSERT's y SELECT's ... 'Esta funcion esta diseada para las versiones antiguas del Visual Basic 'y el VBA de OFFICE 97 (imagino que en el OFFICE 2000 ya existira el 'comando REPLACE) Private Function Duplicar_Comillas(ByVal strMemo As String) As String Dim strResultado As String 'valor devuelto por la funcion

Dim lngPos As Long 'por donde va Dim lngUltima As Long 'ultima comilla encontrada '-------------------'NOTA: esto es tan rebuscado pq en Visual Basic 5 y anteriores 'no existe el comando REPLACE. Tampoco existe en el VBA de OFFICE 97 If (InStr(1, strMemo, "'") = 0) Then strResultado = strMemo Else lngPos = 1 'por donde va lngUltima = 1 'ultima comilla encontrada strResultado = "" Do Until (lngPos = 0) lngPos = InStr(lngPos, strMemo, "'") If lngPos > 0 Then 'Va metiendo cadenas If (strResultado = "") Then strResultado = Left(strMemo, lngPos - 1) & "''" Else strResultado = strResultado & _ Mid(strMemo, lngUltima + 1, lngPos - (lngUltima + 1)) & "''" End If lngUltima = lngPos 'ultima comilla encontrada lngPos = lngUltima + 1 'el +1 se pone pq la cadena es de un caracter End If Loop 'si no acaba en comilla simple If (Right(strMemo, 1) <> "'") Then strResultado = strResultado & Mid(strMemo, lngUltima + 1) End If End If Duplicar_Comillas = strResultado End Function ==================================== 21) Intercambio de imagenes [para controles Image y PictureBox] 'Sirve con controles Image y Picturebox 'Puede haber una image y una picturebox o ser los dos del mismo tipo. 'Realiza un intercambio de imagenes... Public Sub Swap_Imagenes(objDato1 As Object, objDato2 As Object) Dim varTemp As New StdPicture If ((TypeOf objDato1 Is Image Or _ TypeOf objDato1 Is PictureBox) And _ (TypeOf objDato2 Is Image Or _ TypeOf objDato2 Is PictureBox)) Then Set varTemp = objDato1.Picture objDato1.Picture = objDato2.Picture objDato2.Picture = varTemp End If End Sub ==================================== 22) Pasar parmetros a ActiveX [desde ASP] Usa <OBJECT> ... </OBJECT> para los valores por defecto, para pasar parametros a un ActiveX es mas practico crear una propiedad de tipo Collection (porque parec e que solo vas a guardar numeros y cadenas). Todo lo que metas en esa propiedad lo podras usar en el ActiveX para lo que te parezca (ej: por que va a buscar en

una SELECT) y tambien desde tu pagina ASP. Las propiedades de tipo Collection ta mbien tienen los metodos Add (aadir), Remove (eliminar), Count (cuantos tiene)... . Para vaciar la propiedad de tipo Collection, tambien puedes ponerla a NOTHING. Para la propiedad de tipo Collection, tendras que usar por lo menos Public Property Get propiedad() As Collection ... End Property Public Property Set propiedad(c As Collection) ... End Property Ejemplo: Dim colColeccionPropiedades As New Collection '****************************************************************** ' Coleccin usada para pasar las caracteristicas de los treeviews. '****************************************************************** Public Property Get ColeccionPropiedades() As Collection Set ColeccionPropiedades = colColeccionPropiedades End Property Public Property Set ColeccionPropiedades(colPropiedades As Collection) Set colColeccionPropiedades = colPropiedades End Property

==================================== 23) Sacar informacin de la hoja de clculo [VBA] Private Sub Sacar_Info() Dim ap As Application 'la aplicacion EXCEL 97 Dim wb As Workbook 'Un fichero .XLS Dim intNum As Integer 'variable usada en bucle FOR Dim strMemo As String 'mensaje mostrado por pantalla '------------------------------Set ap = Application For intNum = 1 To ap.Workbooks.Count Set wb = ap.Workbooks(intNum) strMemo = "Version de Excel (8.0 => EXCEL 97): " & ap.Version & vbCrLf & _ "Nombre libro: " & wb.Name & vbCrLf & _ "Donde est el libro: " & wb.Path & vbCrLf & _ "N hojas libro: " & wb.Worksheets.Count & vbCrLf & _ "Hoja activa (nombre): " & ap.ActiveSheet.Name & vbCrLf & _ "Celda activa (de esa hoja): " & ap.ActiveCell.Address & vbCrLf & _ "N celdas seleccionadas: " & ap.Selection.Cells.Count & _ Format(ap.Selection.Cells.Rows.Count, " \(#\L") & " x " & _ Format(ap.Selection.Cells.Columns.Count, "#\C\)") & vbCrLf & _ "Impresora usada: " & ap.ActivePrinter & vbCrLf & _ "Se ha guardado?: " & wb.Saved '<*> MsgBox strMemo, vbInformation, "Info del fichero" Next End Sub '<*> - Dentro de la funcin Format(), la "\" sirve para desactivar el ' sig caracter (ej: "\#" te muestra el caracter "#" ) ' - En VBA no es necesario poner delante el objeto Application, es ' decir, Application.ActivePrinter es lo mismo que ActivePrinter, ' pero aqui se crea una variable de tipo Application por motivos

' ' ' ' ' ' ' ' ' ' ' ' '

practicos (si se mete en V.B., hay que cambiar "As Application" por "As Excel.Application"). La variable de tipo Workbook (libro de trabajo de Excel) se crea para no tener que estar poniendo siempre Workbooks(intNum) delante de las propiedades del libro. (si se mete en V.B., hay que cambiar "As Workbook" por "As Excel.Workbook"). Selection es un objeto de la aplicacion que sirve para acceder a las celdas seleccionadas (como minimo hay 1 celda selec). Workbooks es una coleccion que tiene todos los libros (Workbook) abiertos. Cada Workbook, tiene una coleccin WorkSheets Worksheets es una coleccion con todas las hojas del libro. ActiveSheet es la hoja activa (un objeto Worksheet) ActiveCell es la celda activa de la hoja activa (un objeto Cell)

==================================== 24) Esta el PC conectado a Internet? [API] (Esto solo funciona en Windows 95/98. Esta sacado de http://www.allapi.net/tips/ tip028.php) <<< ESTO VA EN UN MODULO >>> Public Const ERROR_SUCCESS = 0& Public Const APINULL = 0& Public Const HKEY_LOCAL_MACHINE = &H80000002 Public ReturnCode As Long Declare Function RegCloseKey Lib "advapi32.dll" (ByVal hKey As Long) As Long Declare Function RegOpenKey Lib "advapi32.dll" Alias "RegOpenKeyA" (ByVal hKey A s Long, _ ByVal lpSubKey As String, phkResult As Long) As Long Declare Function RegQueryValueEx Lib "advapi32.dll" Alias "RegQueryValueExA" (By Val hKey As Long, _ ByVal lpValueName As String, ByVal lpReserved As Long, lpType As Long, lpData As Any, _ lpcbData As Long) As Long <<< ESTO VA EN UN FORMULARIO >>> 'Devuelve TRUE si el PC esta conectado a internet Public Function ActiveConnection() As Boolean Dim hKey As Long Dim lpSubKey As String Dim phkResult As Long Dim lpValueName As String Dim lpReserved As Long Dim lpType As Long Dim lpData As Long Dim lpcbData As Long ActiveConnection = False lpSubKey = "System\CurrentControlSet\Services\RemoteAccess" ReturnCode = RegOpenKey(HKEY_LOCAL_MACHINE, lpSubKey, _ phkResult) If ReturnCode = ERROR_SUCCESS Then hKey = phkResult lpValueName = "Remote Connection" lpReserved = APINULL lpType = APINULL

lpData = APINULL lpcbData = APINULL ReturnCode = RegQueryValueEx(hKey, lpValueName, _ lpReserved, lpType, ByVal lpData, lpcbData) lpcbData = Len(lpData) ReturnCode = RegQueryValueEx(hKey, lpValueName, _ lpReserved, lpType, lpData, lpcbData) If ReturnCode = ERROR_SUCCESS Then If lpData = 0 Then ActiveConnection = False Else ActiveConnection = True End If End If RegCloseKey (hKey) End If End Function

==================================== 25) Mostrar la ventana que Windows usa para elegir un directorio [API] Option Explicit '--- ventana usada para buscar Declare Function SHBrowseForFolder _ Lib "shell32" (lpbi As BrowseInfo) As Long Declare Function SHGetPathFromIDList Lib "shell32" _ (ByVal pidList As Long, ByVal lpBuffer As String) As Long Declare Function lstrcat Lib "kernel32" Alias "lstrcatA" _ (ByVal lpString1 As String, ByVal lpString2 As String) As Long '-- se usa en la funcin strElegirDir() Public Type BrowseInfo hwndOwner As Long pIDLRoot As Long lpszDisplayName As Long lpszTitle As Long ulFlags As Long lpfnCcallBack As Long lParam As Long iImage As Long End Type 'Caracteristicas de la ventana BUSCAR Public Const BIF_BROWSEFORCOMPUTER = &H1000 Public Const BIF_BROWSEFORPRINTER = &H2000 Public Const BIF_BROWSEINCLUDEFILES = &H4000 Public Const BIF_DONTGOBELOWDOMAIN = &H2 Public Const BIF_EDITBOX = &H10 Public Const BIF_RETURNFSANCESTORS = &H8 Public Const BIF_RETURNONLYFSDIRS = &H1 Public Const BIF_STATUSTEXT = &H4 Public Const BIF_MORE_SPACE = &H4 Public Const BIF_USENEWUI = &H40 Public Const BIF_VALIDATE = &H20

'tamao del PATH Public Const MAX_PATH = 260 'strElegir_Dir(): Elige un directorio del disco duro 'Esta funcion tiene una pequea pega: Si eliges un PC de la red y 'das OK, te devuelve una cadena vacia. Public Function strElegir_Dir(Optional strMemo _ As String = "Elige un directorio...") As String Dim lpIDlist As Long Dim strzTitle, strzName As String Dim strBuffer As String * MAX_PATH Dim tBrowseInfo As BrowseInfo '---------------------------------strzTitle = strMemo 'comentario que aparece en la ventana 'BUSCAR' With tBrowseInfo .hwndOwner = 0 '<1> .lpszDisplayName = lstrcat(strzName, "") 'Aade el NULL .lpszTitle = lstrcat(strzTitle, "") 'Aade el NULL .ulFlags = BIF_MORE_SPACE + BIF_RETURNONLYFSDIRS End With 'Guarda el ID del directorio elegido lpIDlist = SHBrowseForFolder(tBrowseInfo) 'Si no es 0 (se pulso ACEPTAR), devuelve el nombre del directorio elegido If (lpIDlist) Then 'Mete el directorio en una variable (strBuffer) SHGetPathFromIDList lpIDlist, strBuffer 'Lo pone en minusculas y quita nulos strBuffer = LCase(strBuffer) strElegir_Dir = Left(strBuffer, InStr(strBuffer, vbNullChar) - 1) Else strElegir_Dir = "" End If '<1>: Con esto aparece en la esquina superior izquierda de la pantalla. ' Para evitar eso, cambiar el 0 por <formulario>.hWnd ' Si el .hwnd es 0, siempre aparece en una esquina. End Function

==================================== 26) Donde estn 'Mi PC' y otros iconos en el registro [RegEdit] Dentro de HKEY_CLASSES_ROOT\CLSID\ hay esto (entre otros): {00020D75-0000-0000-C000-000000000046} {208D2C60-3AEA-1069-A2D7-08002B30309D} {20D04FE0-3AEA-1069-A2D8-08002B30309D} {21EC2020-3AEA-1069-A2DD-08002B30309D} {2227A280-3AEA-1069-A2DE-08002B30309D} {645FF040-5081-101B-9F08-00AA002F954E} {FBF23B42-E3F0-101B-8488-00AA003E56F8} : : : : : : : Bandeja de entrada Entorno de red Mi PC Panel de control Impresoras Papelera Internet Explorer

Sabiendo esto, puedes crearte el icono del panel de control (o cualquier otro) en el escritorio (el escritorio es C:\WINDOWS\ESCRITORIO\ en Windows 95 si usas la instalacion estandar) o donde te parezca. Se consigue haciendo esto: cualquier_cosa.{codigo}

Ejemplo (crea el panel de control, aunque se llame "Panel ctrl"): md "Panel ctrl".{21EC2020-3AEA-1069-A2DD-08002B30309D}

==================================== 27) Como saber si se est usando Windows NT o no [API] Private Type OSVERSIONINFO dwOSVersionInfoSize As Long dwMajorVersion As Long dwMinorVersion As Long dwBuildNumber As Long dwPlatformId As Long szCSDVersion As String * 128 End Type Const VER_PLATFORM_WIN32_NT = 2 Declare Function GetVersionEx Lib "kernel32" Alias "GetVersionExA" _ (lpVersionInformation As OSVERSIONINFO) As Long 'Para saber si se esta en Windows NT o no Function IsWindowsNT() As Boolean Dim lRC As Long Dim typOSInfo As OSVERSIONINFO '---------------------------------------------typOSInfo.dwOSVersionInfoSize = Len(typOSInfo) lRC = GetVersionEx(typOSInfo) IsWindowsNT = (typOSInfo.dwPlatformId = VER_PLATFORM_WIN32_NT) End Function

==================================== 28) Usar funciones definidas por usuario en Excel 97 [VBA] - Abre Excel 97 - Abre / crea una hoja de clculo - Pulsa ALT-F11 para entrar en el editor de Visual Basic - Haz clic en Insertar.Mdulo (con el mdulo de clase esto no sirve) - Crea una o ms funciones de tipo 'Public' - Sal del editor y vuelve a Excel Ejemplo de funcin: Public Function blnFinDeSemana(datFecha As Date) As Boolean 'DatePart() devuelve 6 si es sabado y 7 si es domingo blnFinDeSemana = (DatePart("w", datFecha, vbMonday) >= 6) End Function Una vez hecho esto, puedes hacer cosas como: =blnFinDeSemana(HOY( ))

====================================

29) Sacar el n de dias entre fechas sin contar fines de semana '--Dos formas de sacar el n de dias entre dos fechas sin contar los '--fines de semana, ambos incluidos: '-- DateDiff_FinDeSemana_OLD() es algo mas lenta que la nueva version, '-- pero entre una fecha y otra debe haber unos cuantos siglos de '-- diferencia para que se note '## VERSION ANTIGUA ## Private Function DateDiff_FinDeSemana_OLD(ByVal dtFechaInicio As Date, _ ByVal dtFechaFin As Date) As Long Dim lngDias As Long '---------------------------lngDias = 0 'ignora las horas dtFechaInicio = Format(dtFechaInicio, "yyyy/mm/dd") dtFechaFin = Format(dtFechaFin, "yyyy/mm/dd") '--- comprueba si la fecha inicio es mayor que la fecha fin If (dtFechaInicio <= dtFechaFin) Then Do Until dtFechaInicio > dtFechaFin 'si se mete por el IF es sabado o domingo If (Format(dtFechaInicio, "w", vbMonday, vbFirstJan1) >= 6) Then dtFechaInicio = dtFechaInicio + 1 Else dtFechaInicio = dtFechaInicio + 1 lngDias = lngDias + 1 End If Loop Else Do Until dtFechaInicio < dtFechaFin 'si se mete por el IF es sabado o domingo If (Format(dtFechaInicio, "w", vbMonday, vbFirstJan1) >= 6) Then dtFechaInicio = dtFechaInicio - 1 Else dtFechaInicio = dtFechaInicio - 1 lngDias = lngDias - 1 End If Loop End If '--DateDiff_FinDeSemana_OLD = lngDias End Function '## VERSION NUEVA ## Private Function DateDiff_FinDeSemana(ByVal dtFechaInicio As Date, _ ByVal dtFechaFin As Date) As Long Dim lngDias As Long Dim dtTemp As Date Dim blnInicioMayorFin As Boolean '---------------------------lngDias = 0 'comprueba si inicio > fin blnInicioMayorFin = (dtFechaInicio > dtFechaFin) If (blnInicioMayorFin) Then dtTemp = dtFechaInicio dtFechaInicio = dtFechaFin dtFechaFin = dtTemp End If

'ignora las horas dtFechaInicio = Format(dtFechaInicio, "yyyy/mm/dd") dtFechaFin = Format(dtFechaFin, "yyyy/mm/dd") '--If (dtFechaInicio = dtFechaFin) Then lngDias = 1 Exit Function ElseIf (dtFechaInicio < dtFechaFin And _ (dtFechaFin - dtFechaInicio + 1) Mod 7 = 0) Then '<*> '<*> esto ocurre si las fechas van de un lunes a un domingo ' (entre otras combinaciones posibles) lngDias = 5 * DateDiff("w", dtFechaInicio, dtFechaFin + 1) DateDiff_FinDeSemana = lngDias Exit Function ElseIf (dtFechaInicio < dtFechaFin) Then Do Until dtFechaInicio >= dtFechaFin If (dtFechaFin - dtFechaInicio >= 5) Then Select Case (Format(dtFechaInicio, "w", vbMonday)) Case 7: 'domingo dtFechaInicio = dtFechaInicio + 1 'num dias no cambia Case 6: 'sabado dtFechaInicio = dtFechaInicio + 2 'num dias no cambia Case 5: 'viernes dtFechaInicio = dtFechaInicio + 3 lngDias = lngDias + 1 Case 4: 'jueves dtFechaInicio = dtFechaInicio + 4 lngDias = lngDias + 2 Case 3: 'miercoles dtFechaInicio = dtFechaInicio + 5 lngDias = lngDias + 3 Case 2: 'martes dtFechaInicio = dtFechaInicio + 6 lngDias = lngDias + 4 Case 1: 'lunes dtFechaInicio = dtFechaInicio + 7 lngDias = lngDias + 5 End Select Else lngDias = lngDias + (dtFechaFin - dtFechaInicio + 1) dtFechaInicio = dtFechaFin Select Case (Format(dtFechaFin, "w", vbMonday)) Case 7: lngDias = lngDias - 2 'se quitan dias Case 6: lngDias = lngDias - 1 'se quitan dias Case 1 To 5: 'num dias no cambia End Select End If Loop End If '--If (blnInicioMayorFin) Then DateDiff_FinDeSemana = -1 * lngDias Else DateDiff_FinDeSemana = lngDias End If

End Function

==================================== 30) Comprobar si un item de una coleccion existe 'Comprueba si el item indicado (n o clave) de la coleccion existe Public Function blnItemExists(colCollection As Collection, _ strID As String) As Boolean Dim varJoker As Variant ' it's used to check if an item exist '-----------------------------------------------------On Error Resume Next Err.Clear 'si no existe -> error If (colCollection Is Nothing) Then '-- es nothing blnItemExists = False ElseIf (colCollection.Count = 0) Then '-- esta vacia blnItemExists = False Else '-- puede que exista If (IsNumeric(strID)) Then varJoker = colCollection(CLng(strID)) Else varJoker = colCollection(strID) End If If (Err.Number) Then 'si Err.number = 0 ---> encontrado blnItemExists = False Else blnItemExists = True End If End If On Error GoTo 0 Err.Clear End Function

==================================== 31) Comprueba si todos los item indicados de una coleccin existen '## Comprueba si TODOS los item indicados (n o clave) de la coleccion '## existen Public Function blnItemExistsEX(colCollection As Collection, _ ParamArray strID() As Variant) As Boolean Dim varJoker As Variant ' sirve para saber si el item existe Dim lngNum As Long '-----------------------------------------------------On Error Resume Next Err.Clear 'If the item doesn't exist -> error If (colCollection Is Nothing) Then '-- es nothing blnItemExistsEX = False ElseIf (colCollection.Count = 0) Then '-- esta vacia blnItemExistsEX = False ElseIf (UBound(strID) < 0) Then '-- no se pasaron campos blnItemExistsEX = False Else '-- puede que existan todos '-- Si uno no existe, no necesita seguir For lngNum = 0 To UBound(strID) If (IsNumeric(strID(lngNum))) Then

varJoker = colCollection(CLng(strID(lngNum))) Else varJoker = colCollection(strID(lngNum)) End If 'si Err.number = 0 [el ELSE], sigue comprobando If (Err.Number) Then blnItemExistsEX = False Exit For Else blnItemExistsEX = True End If Next End If On Error GoTo 0 Err.Clear End Function

==================================== 32) Comprobar si una tabla de Access 97 existe [VBA] 'Sirve para saber si las tablas de una base de datos ACCESS existen o no. 'Ejemplo: 'If (blnTablaExiste("Webs")) Then ' SQL = "DELETE FROM WEBS" 'Else ' SQL = "CREATE TABLE WEBS (PAGINA_WEB TEXT(127) TIPO_WEB BYTE)" 'End If Public Function blnTablaExiste(strTabla As String) As Boolean Dim intCont As Integer Dim strTablaAccess As String '-------------------------------If (CurrentDb.TableDefs.Count = 0 or Trim(strTabla)="") Then blnTablaExiste = False Else 'Ese -1 se pone pq la primera tabla tiene indice 0. intCont = CurrentDb.TableDefs.Count - 1 Do Until (intCont < 0) strTablaAccess = Trim(UCase(CurrentDb.TableDefs(intCont).Name)) If (Trim(UCase(strTabla)) <> strTablaAccess) Then intCont = intCont - 1 Else Exit Do 'Tabla encontrada End If Loop blnTablaExiste = (intCont >= 0) End If End Function

==================================== 33) Lista de errores del VBA de Access 97 [VBA] Puedes probar y responder a estos errores interceptables mediante la instruccin On Error y el objeto Err. Los nmeros de error no usados en el intervalo de 1 a 1000 estn reservados para futuras versiones de Visual Basic. --- 1 - 200 --3 Se ha encontrado Return sin Gosub

5 6 7 9 10 11 13 14 16 17 18 20 28 35 47 48 49 51 52 53 54 55 57 58 59 61 62 63 67 68 70 71 74 75 76 91 92 93 94 97

Llamada o argumento a procedimiento no vlido Desbordamiento No hay suficiente memoria El subndice est fuera del intervalo Esta matriz est bloqueada de manera fija o temporal Divisin entre cero No coinciden los tipos No hay suficiente espacio de cadena La expresin de cadena es demasiado compleja No se puede realizar la operacin solicitada Se ha producido una interrupcin por parte del usuario Reanudar sin errores No hay suficiente espacio de pila No se ha definido Sub, Function o Property Hay demasiados clientes de la aplicacin DLL Error al cargar la DLL Convencin de llamada a DLL incorrecta Error interno Nombre o nmero de archivo incorrecto No se puede encontrar el archivo especificado Modo de archivo incorrecto El archivo ya est abierto Error en dispositivo de entrada y salida El archivo ya existe Longitud de registro incorrecta Disco lleno Entrada pas el final del archivo Nmero de registro incorrecto Hay demasiados archivos abiertos Dispositivo no disponible Permiso no autorizado El disco no est listo No se puede cambiar el nombre a una unidad de disco diferente Error de acceso a la ruta o archivo No se ha encontrado la ruta de acceso Variable del objeto o variable de bloque With no establecida El bucle For no se ha inicializado Cadena de patrn no vlida Uso de Null no vlido Imposible llamar a un procedimiento friend de un objeto que no tiene una instancia de la clase definida --- 201 - 400 --298 No se puede cargar la DLL especificada del sistema 320 No se pueden utilizar nombres de dispositivos de caracteres en nombres de archivos 321 El formato de archivo no es vlido 322 Imposible crear un archivo temporal necesario 325 Formato no vlido en el archivo de recursos 327 No se encontr el valor del dato 328 Parmetro no vlido. No se puede escribir matrices 335 No se puede acceder al registro del sistema 336 El componente ActiveX no est registrado correctamente 337 No se encontr el componente ActiveX 338 El componente ActiveX no se ejecut correctamente 360 Ya se ha cargado el objeto 361 No se puede cargar o descargar este objeto 363 No se ha encontrado el control ActiveX especificado 364 El objeto se ha descargado 365 No se puede descargar dentro de este contexto 368 El archivo especificado no est actualizado. Este programa

necesita una versin ms reciente El objeto especificado no se puede utilizar como un formulario propietario para Show() 380 Valor de propiedad no vlido 381 El ndice de la matriz de propiedades no es vlido 382 Set no se admite en tiempo de ejecucin 383 Set no se admite (propiedad de slo lectura) 385 Se necesita un ndice de matriz de propiedad 387 Set no est permitido 393 Imposible ejecutar Property Get en tiempo de ejecucin 394 Imposible ejecutar Property Get en una propiedad de slo escritura 400 El formulario ya est mostrado; no se puede mostrar en forma modal --- 401 - 600 --402 Primero debe cerrar u ocultar el formulario modal superior 419 Permiso denegado para utilizar el objeto 422 No se encontr la propiedad 423 No se ha encontrado la propiedad o el mtodo 424 Se requiere un objeto 425 El uso del objeto no es vlido 429 El componente ActiveX no puede crear el objeto o devolver una referencia a este objeto 430 La clase no soporta automatizacin OLE 432 No se ha encontrado un nombre de archivo o un nombre de clase durante la operacin de Automatizacin OLE 438 El objeto no acepta esta propiedad o mtodo 440 Error de automatizacin OLE 442 Se ha perdido la conexin con la biblioteca de tipos o con la biblioteca de objetos para procesos remotos 443 El objeto de Automatizacin OLE no tiene un valor predeterminado 445 El objeto no admite esta accin 446 El objeto no admite argumentos con nombre 447 El objeto no acepta la configuracin regional vigente 448 No se ha encontrado el argumento con nombre 449 El argumento no es opcional 450 Nmero de argumentos incorrecto 451 El objeto no es una coleccin 452 Nmero ordinal no vlido 453 La funcin no ha sido definida en la biblioteca (DLL) 454 No se ha encontrado el recurso de cdigo 455 Error en el bloqueo de los recursos del cdigo 457 La tecla ya est asociada con algn elemento de est coleccin 458 La variable utiliza un tipo OLE no admitido en Visual Basic 459 El objeto o la clase no admite el conjunto de eventos 460 El formato del Portapapeles no es vlido 461 El formato especificado no coincide con el formato de los datos 480 No se puede crear una imagen AutoRedraw 481 Imagen no vlida 482 Error de impresora 483 El controlador de impresora no admite la propiedad especificada 484 Problemas al obtener informacin de la impresora desde el sistema; asegrese de que la impresora est configurada correctamente 485 El tipo de imagen no es vlido 486 Can't print form image to this type of printer 520 No se puede vaciar el Portapapeles 521 No se puede abrir el Portapapeles --- 601 - 1000 --735 Imposible guardar el archivo en el directorio TEMP 371

744 No se encontr el texto de bsqueda 746 Sustituciones demasiado largas --- > 1000 --3265 Tabla no existe [error de DAO] 31001 Sin memoria 31004 Ningn objeto 31018 La clase no est establecida 31027 Unable to activate object 31032 Imposible crear el objeto incrustado 31036 Error al guardar el archivo 31037 Error al cargar el archivo

==================================== 34) Como adivinar la password de bases de datos cuando usas ODBC [RegEdit] [esto esta probado en Windows 95 y NT, pero apuesto a que sirve en mas versiones ] :) a) Ejecutar REGEDIT.EXE b1) Si la conexion ODBC esta dentro de las 'DSN de usuario', irse a: HKEY_CURRENT_USER\Software\ODBC\ODBC.INI\(nombre conexion) Ej: HKEY_CURRENT_USER\Software\ODBC\ODBC.INI\MOTOS b2) Si la conexion ODBC esta dentro de las 'DSN de sistema', irse a: HKEY_LOCAL_MACHINE\Software\ODBC\ODBC.INI\(nombre conexion) Ej: HKEY_LOCAL_MACHINE\Software\ODBC\ODBC.INI\COCHES c) En la mitad derecha del REGEDIT buscar 'PWD' (password) y ya tienes la password sin encriptar. ;) [Estos de Micro$oft son un poco cutres, no?]

==================================== 35) Desactivar opciones de NT [Regedit] Puedes controlar los botones que aparecen activados en el cuadro de dilogo "Segur idad de Windows NT" (el que sale con CTRL-ALT-SUPR). Solo hay que usar estos tru cos del registro: Desactivar botn "Bloquear estacin de trabajo" (Lock Workstation): Hive: HKEY_CURRENT_USER Key: Software\Microsoft\Windows\CurrentVersion\Policies\System Name: DisableLockWorkstation Type: REG_DWORD Value: 1 (el 1 es para desactivar ; el 0 para activar) Desactivar botn "Administrador de tareas" (Task Manager): Hive: HKEY_CURRENT_USER Key: Software\Microsoft\Windows\CurrentVersion\Policies\System Name: DisableTaskMgr Type: REG_DWORD Value: 1 (el 1 es para desactivar ; el 0 para activar) Desactivar botn "Cambiar contrasea" ( Change Password): Hive: HKEY_CURRENT_USER

Key: Software\Microsoft\Windows\CurrentVersion\Policies\System Name: DisableChangePassword Type: REG_DWORD Value: 1 (el 1 es para desactivar ; el 0 para activar) Desactivar botn "Cerrar Sesin" (Logoff ): Hive: HKEY_CURRENT_USER Key: Software\Microsoft\Windows\CurrentVersion\Policies\Explorer Name: NoLogoff Type: REG_DWORD Value: 1 (el 1 es para desactivar ; el 0 para activar) Cuando se desactiva, la opcin "Cerrar Sesin" desaparece del men inicio. :-D Desactivar botn "Cerrar el sistema" (Shutdown): Hive: HKEY_CURRENT_USER Key: Software\Microsoft\Windows\CurrentVersion\Policies\Explorer Name: NoClose Type: REG_DWORD Value: 1 (el 1 es para desactivar ; el 0 para activar) Cuando se desactiva, la opcin "Apagar el sistema" desaparece del men inicio. :-D

==================================== 36) Sub que imita al comando SWAP del Qbasic 'intercambia dos valores. 'Sirve con Integer, Long, String,.... 'no sirve con objetos Public Sub Swap(varDato1 As Variant, varDato2 As Variant) Dim varTemp As Variant '-----------------------------varTemp = varDato1 varDato1 = varDato2 varDato2 = varTemp End Sub Para que sirva con objetos debe quedar asi: Public Sub Swap(objObjeto1 As Object, objObjeto2 As Object) Dim varTemp As Variant '-----------------------------Set objTemp = objObjeto1 Set objObjeto1 = objObjeto2 Set objObjeto2 = objTemp End Sub

==================================== 37) Formato de celdas de una hoja Excel [VBA] Hay varias formas de hacer esto: ActiveWorkbook.ActiveSheet.Range("A1").NumberFormat = "0.00;-0.00;0" ActiveWorkbook.ActiveSheet.Cells(1, 1).NumberFormat = "0.00;-0.00;0" ActiveWorkbook.ActiveSheet.Offset(1, 3).NumberFormat = "0.00;-0.00;0"

==================================== 38) Abrir archivos .HLP en Excel [VBA] Private Declare Function ShellExecute Lib "shell32.dll" Alias "ShellExecuteA" (B yVal hwnd As Long, _ ByVal lpOperation As String, ByVal lpFile As String, ByVal lpParameters As St ring, _ ByVal lpDirectory As String, ByVal nShowCmd As Long) As Long Private Sub CommandButton1_Click() ShellExecute 0, "open", "c:\windows\escritorio\prueba.hlp", "", "", 1 End Sub

Los parmetros de la API ShellExecute son: * hwnd: Handle ("manejador") de la ventana "padre"; le ponemos 0 (el escritorio de Windows) * lpOperation: Operacin a ejecutar con el archivo, podra ser "open", "print", "exp lore", etc. * lpFile: El archivo en cuestin * lpParameters: Si el archivo es un ejecutable, pondramos aqu los parmetros a pasar le, como es un *.hlp, ponemos "" * lpDirectory: Directorio de trabajo por defecto * nShowCmd: Modo en que se mostrar la ventana al abrir el archivo; pondremos 1 pa ra modo "normal" Para determinar la ruta del archivo de ayuda, lo mejor ser que lo tengas en la mi sma carpeta que la hoja de clculo, que ambos estn "juntitos", as podrs saber la ruta del archivo *.hlp mediante: Application.ActiveWorkbook.Path O sea, para abrir un archivo TuArchivo.hlp, que est en la misma carpeta que la ho ja de clculo actual (por ejemplo, en el directorio raz de un CD) utiliza: ShellExecute 0, "open", Application.ActiveWorkbook.Path & "\TuArchivo.hlp", "", "", 1

==================================== 39) Msgbox que se autodestruye [VB] Entra en Proyecto.Referencias (si estas en Visual Basic) o en Herramientas.Referencias (si ests en el VBA de Excel). Busca "Windows Scripting Host Model (ver. 1.0)" (es el fichero WSHOM.OCX). Nota: Puede que no aparezca en la lista de referencias y tengas que buscarlo usando el boton Examinar. 'la enumeracion vbMsgBoxResult tiene los valores que devuelve Msgbox() 'la enumeracion vbMsgBoxStyle tiene las caracteristicas de la ventana (vbYesNo,. ..) Public Function MyBox(strMemo As String, strTitulo As String, tiempo As Byte, _ Optional Botones As VbMsgBoxStyle = vbOKOnly) As VbMsgBoxResult 'hay que hacer referencia al ocx -> wshom.ocx Dim MyShell As IWshRuntimeLibrary.IWshShell_Class Set MyShell = New IWshRuntimeLibrary.IWshShell_Class MyBox = MyShell.PopUp(strMemo, tiempo, strTitulo, Botones)

End Function Ejemplo: dim intBoton as vbMsgBoxResult 'muestra un mensaje. Si pasan 10 segundos, elige la opcion "NO" intBoton = MyBox("Continuar? (s/n)", "Error", 10, vbYesNo) if (intBoton = -1) then intBoton = vbYesNo if (intBoton = vbNo) Then ' .... cosas que hace si pulsa NO .... elseif (intBoton = vbYes) Then ' .... cosas que hace si pulsa YES .... end if ==================================== 40) Pruebas con el 'mueco diablico' de Office 97 [VBA] 'Pruebas con el ayudante de Office 97 Private Sub Probando() Dim opc As Integer Dim bal As Balloon Set bal = Assistant.NewBalloon With bal 'tipo de 'balloon' (pueden ser modales o no) .Mode = msoModeModal 'cabecera (esto sale en negrita) .Heading = "Webs" 'texto con foto .Text = "{bmp c:\windows\burbujas.bmp}" & vbCrLf & _ "Elige una de estas webs:" '<*> 'se indica que usa botones .BalloonType = msoBalloonTypeButtons 'botones (el objeto balloon desaparece si pulsas uno de estos) 'el tope esta en 5 etiquetas. El indice ms bajo es el 1... .Labels(1).Text = "http://www.vb-helper.com/"; .Labels(2).Text = "http://www.marca.com"; .Labels(3).Text = "http://www.mvps.org/ccrp/"; .Labels(4).Text = "http://www.bromamania.net/"; .Labels(5).Text = "http://www.altavista.com/"; 'checkboxes .CheckBoxes(1).Text = "Guardar web elegida" 'cuantos botones aparecen (como en la msgbox) .Button = msoButtonSetOK 'muestra el objeto Balloon y guarda la opcion elegida opc = .Show 'si elige 'Aceptar' devuelve -1 'Si la checkbox esta marcada, mete la web en WEBS.TXT If (.CheckBoxes(1).Checked) Then Open "C:\WEBS.TXT" For Append As #1 Print #1, .Labels(opc).Text Close #1 End If 'carga la web elegida Select Case (opc) Case -1: 'ha pulsado boton Aceptar Case 1 To 5: Shell "c:\archivos de programa\" & _ "internet explorer\iexplore """ & _ .Labels(opc).Text & """", vbNormalFocus '<*> End Select End With '<*> puede que tengas que cambiar el path

End Sub

==================================== 41) Sacar nombres de tablas y campos en SQL Server y Access 97 Para sacar los nombres de las tablas en SQL SERVER select * from sysobjects where upper(xtype) = upper('U') Para sacar todas las tablas y sus campos en SQL SERVER select O.name Tabla, C.name Campo from sysobjects O inner join syscolumns C on C.id = O.id and upper(O.xtype) = upper('U') order by O.name Para sacar los nombres de las tablas en ACCESS 97 SELECT M.Name FROM MSysObjects AS M WHERE (((M.LvProp) Is Not Null) AND ((M.ParentId)=(SELECT N.ID FROM MSysObjects AS N WHERE N.Name = 'Tables')) AND ((M.Type)=1)) Para sacar los nombres de los campos en ACCESS 97 1) SELECT TOP 1 * FROM (TABLA) 2) (bucle FOR para sacar los nombres de los campos) (en Access 97 hay que dar permisos de lectura en la tabla MSysObjects para poder acceder a esa tabla de sistema desde VB) ==================================== 42) Usar Split( ) para devolver la extension de un fichero 'This is a routine for returning the correct file extensions catering to all pos sible input values. ' "TestFile.txt" ==> "txt" (Normal filename) ' "Test.File.txt" ==> "txt" (Filename with extra ".") ' "TestFile." ==> "" (Filename with "." but without extension) ' "TestFile" ==> "" (Filename without extension) ' "" ==> "" (Filename input is null string) 'Function FileExtension(sFilename As String) As String Dim vExtension As Variant vExtension = Split(sFilename, ".") If UBound(vExtension) > 0 Then FileExtension = vExtension(UBound(vExtension)) Else FileExtension = "" End If End Function ==================================== 43) Separar argumentos pasados a un programa VB [funcin Command( )] '=========================================================================== 'Se parece al ejemplo de la funcion command() del VB 5 '[pero esta funcion admite ficheros y directorios con espacios] :-) 'Forma de usarla: ' Dim args As Variant ' args = GetCommandLine(1) 'solo interesa 1 argumento...

' ... .... .... .... ' if (Dir(args(1)) = "") Then ' Msgbox "Fichero no existe", vbExclamation, "ERROR" ' End ' Else ' .... ' End if Public Function GetCommandLine(Optional intMaxArgs As Integer) Dim blnComillas As Boolean Dim intNum As Integer Dim strCaracter As String Dim strArgumentos As String Dim intLongitudArgs As Integer Dim blnArg As Boolean Dim intNumArgs As Integer 'Comprueba si se paso intMaxArgs If IsMissing(intMaxArgs) Then intMaxArgs = 10 'Crea un array del tamao indicado en intMaxArgs ReDim argArray(intMaxArgs) intNumArgs = 0 blnArg = False 'Saca los argumentos de la linea de comandos strArgumentos = Command() intLongitudArgs = Len(strArgumentos) blnComillas = False 'Comprueba caracter a caracter For intNum = 1 To intLongitudArgs strCaracter = Mid(strArgumentos, intNum, 1) 'Comprueba si es un espacio o tabulador If (strCaracter <> " " And strCaracter <> vbTab) Then 'Neither space nor tab. 'Test if already in argument. If Not blnArg Then 'Comienza nuevo argumento 'Si ya tiene todos los que necesita, no sigue If intNumArgs = intMaxArgs Then Exit For intNumArgs = intNumArgs + 1 If strCaracter = """" Then blnComillas = True blnArg = True ElseIf blnArg And blnComillas Then If strCaracter = """" Then blnComillas = False blnArg = False End If End If 'Aade caracter If strCaracter <> """" Then argArray(intNumArgs) = argArray(intNumArgs) & strCaracter End If Else 'Se encontro un espacio o tabulacion 'Comprueba si se han cerrado comillas (blnComillas = False) If Not blnComillas Then blnArg = False Else 'En Win'9x el nombre de fichero puede tener espacios 'si esta entre comillas las tabulaciones y espacios 'se cuentan como espacios argArray(intNumArgs) = argArray(intNumArgs) & " " End If

End If Next 'Cambia tamao de array ReDim Preserve argArray(intNumArgs) 'La funcin devuelve el array GetCommandLine = argArray() End Function

==================================== 44) Pruebas para insertar texto con Word usando macros [VBA] Public Sub prueba_word() Dim docWord97 As Document Dim parParrafo As Paragraph '---------------------------------'MsgBox Asc(Mid(ThisDocument.Paragraphs(1).Range, 2, 1)) 'THISDOCUMENT es el documento con la macro MsgBox ThisDocument.Range, , ThisDocument.Name 'Todo el documento.... Set parParrafo = ThisDocument.Paragraphs(1) 'empieza por 1 parParrafo.Range.InsertParagraphBefore 'inserta un parrafo en blanco al princi pio Set parParrafo = ThisDocument.Paragraphs(1) 'se coloca en el 1er parrafo parParrafo.Range.Font.Name = "Courier new" 'CHR(11) es un salto de linea manual (^l). [TECLA: SHIFT-ENTER] 'vbCRLF es el fin de parrafo (^p). [TECLA: ENTER] parParrafo.Range = "TRUCOS WARCRAFT" & Chr(11) & _ "There can be only one" & Chr(11) & _ "It is a good day to die" & Chr(11) & _ "sally shears" & Chr(11) & _ "pot of gold" & vbCrLf End Sub

==================================== 45) Insertar un fichero de texto en Word usando macros [VBA] Se consigue con el metodo InsertFile del objecto Selection. Ejemplo: Selection.InsertFile FileName:="d:\leeme.txt", Range:="", _ ConfirmConversions:=False, Link:=False, Attachment:=False

==================================== 46) Insertar un trozo de una hoja de clculo en Word usando macros [VBA] Se consigue con el metodo InsertFile del objecto Selection. Con RANGE se indica un bloque de celdas. Los datos aparecen dentro de una tabla Ejemplo: Selection.InsertFile FileName:="C:\probando.xls", Range:="A1:C4", _ ConfirmConversions:=False, Link:=False, Attachment:=False

==================================== 47) Rellenar un grafico de Microsoft Graph desde Visual Basic 6 [VB5 , VB6] 'cnn es una variable global definida de esta forma: Dim cnn as New ADODB.Conne ction 'chtGraf es el grafico que se esta usando ( Set chtGraf = Me.chtGrafico_Horas ) 'Debes tener instalado el Microsoft Graph (viene con el Office 97 / 2000) ' Todas las constantes usadas: 'Const cte_MSOPATTERN_SOLID_DIAMOND = 39 'relleno de la primera columna 'Const cte_XLDATA_LABELS_SHOW_VALUE = 2 'mostrar valores '--- ctes usadas para rellenar el DataGrid --'Const cteFILA_TOTAL As Long = 2 'esta es la primera barra 'Const cteCOL_NOMBRE As Long = 1 'Aqui se mete rs.Fields("NOM_PRJ") 'Const cteCOL_NUMERO As Long = 2 'Aqui se mete rs.Fields("NUM_DIAS") 'Const cteFILA_TITULO As Long = 1 'esto aparece encima de la leyenda (si col > 1 ) 'Const cteCOL_TITULO As Long = 2 'esto aparece encima de la leyenda (si fila = 1 ) Private Sub Actualizar_Grafico_Tab2(Optional ByVal strCod As String = cteVACIAR) Dim chtGraf As Chart 'Grafico Microsoft Graph Dim strSQL As String 'Comando SQL usado para generar este grafico Dim rs As New ADODB.Recordset 'Recordset usado para crear este grafico Dim intFila As Integer 'n de fila del DataSheet Dim lngTotal As Long 'Suma de todos los COUNT(*) Dim strDesde As String 'Fecha usada en el SQL ('fecha desde') Dim strHasta As String 'Fecha usada en el SQL ('fecha hasta') '-----------' nota: la unica vez que strCod no es un numero es al cargarse el formulario. ' == '=== GENERA EL COMANDO SQL USADO PARA CREAR EL GRAFICO DE BARRAS ' == If IsNumeric(strCod) Then '-- convierte las fechas de los dtPicker a SQL Server strDesde = " convert(DateTime, '" & Format(dtpDesde.Value, "dd/mm/yyyy") & " ') " strHasta = " convert(DateTime, '" & Format(dtpHasta.Value, "dd/mm/yyyy") & " ') " '-- Genera el comando strSQL = "select pt.idproyecto [ID_PRJ], pr.nombre [NOM_PRJ], " & vbCrLf & _ "pt.idpersonal [ID_PER], pe.nombre [NOM_PER], " & vbCrLf & _ "count(*) [NUM_DIAS]" & vbCrLf & _ "from partestrabajo pt" & vbCrLf & _ "inner join personal pe on pt.idpersonal = pe.idpersonal" & vbCrLf & _ "inner join proyectos pr on pt.idproyecto = pr.idproyecto" & vbCrLf & _ "Where pt.idpersonal = " & strCod & " and " & vbCrLf & _ " pt.fparte between " & strDesde & " and " & strHasta & vbCrLf & _ "group by pt.idproyecto, pt.idpersonal," & vbCrLf & _ " pr.nombre , pe.nombre" & vbCrLf & _ "order by pr.nombre" Else strSQL = "" strCod = cteVACIAR End If ' == '=== BORRA TODO ' ==

Set chtGraf = Me.chtGrafico_Horas If Not IsNumeric(strCod) Then 'la columna usada para 'TOTAL' tiene un formato especial 'Todo este WITH sirve para que esa columna tenga un relleno... With chtGraf.object.SeriesCollection(1) 'Tipo de relleno (la mejor forma de adivinar los numeros que se meten 'en esta propiedad es entrar en Excel 97/2000 y crear un grfico de barras m ientras 'se esta ejecutando una macro.) .Fill.Patterned Pattern:=cte_MSOPATTERN_SOLID_DIAMOND .Fill.Visible = True 'Colores usados en el relleno (la mejor forma de adivinar los numeros que se meten 'en estas propiedades es entrar en Excel 97/2000 y crear un grfico de barra s mientras 'se esta ejecutando una macro.) .Fill.ForeColor.SchemeColor = 8 .Fill.BackColor.SchemeColor = 42 End With End If 'Vacia el grafico (los colores, rellenos,... de cada barra NO se pierden ) 'Esto hay que hacerlo porque alguna vez me ha salido el error de 'Memoria agot ada' cuando 'se tienen dos grficos o ms. chtGraf.object.Application.DataSheet.Cells.Clear ' == '=== CREA EL GRAFICO (EL NUMERO DE BARRAS DEPENDE DE LO QUE DEVUELVA '=== LA SELECT, PERO SIEMPRE TIENE POR LO MENOS UNA) ' == If (IsNumeric(strCod)) Then rs.Open strSQL, cnn, adOpenStatic With chtGraf.object.Application.DataSheet 'Columna 'Total' (siempre aparece) .Cells(cteFILA_TOTAL, cteCOL_NOMBRE) = "TOTAL" .Cells(cteFILA_TOTAL, cteCOL_NUMERO) = 0 'mete por defecto 0 'De quien son esas cifras (esto aparece entre grafico y leyenda) .Cells(cteFILA_TITULO, cteCOL_TITULO) = "Proyectos de " & _ cmbPersonal.Text & vbCrLf & _ "(" & Format(dtpDesde.Value, "dd/mmm/yyyy") & " - " & _ Format(dtpHasta.Value, "dd/mmm/yyyy") & ")" End With 'Nombres de los proyectos lngTotal = 0 intFila = cteFILA_TOTAL + 1 'para que empiece por DataSheet.Cells(3,1) 'si no hay registros, saldr una sola barra a cero (la del TOTAL) Do Until rs.EOF With chtGraf.object.Application.DataSheet 'nombre del proyecto (en la leyenda tambien sale el n dias) .Cells(intFila, cteCOL_NOMBRE) = Trim(rs.Fields("NOM_PRJ")) & _ " (" & CLng(rs.Fields("NUM_DIAS")) & ")" 'numero de dias que se esta con ese proyecto .Cells(intFila, cteCOL_NUMERO) = CLng(rs.Fields("NUM_DIAS")) End With 'cambia el valor de 'lngTotal' (la columna total se actualiza la ultima) lngTotal = lngTotal + rs.Fields("NUM_DIAS") 'cambia de fila en el control Microsoft Graph intFila = intFila + 1 'pasa al registro siguiente rs.MoveNext Loop

'Valores (los select count(*)) rs.Close 'Columna 'Total' (siempre aparece) With chtGraf.object.Application.DataSheet .Cells(cteFILA_TOTAL, cteCOL_NOMBRE) = .Cells(cteFILA_TOTAL, cteCOL_NOMBR E) & _ " (" & lngTotal & ")" .Cells(cteFILA_TOTAL, cteCOL_NUMERO) = lngTotal End With 'Este bucle FOR sirve para que se muestren los numeros encima de 'las barras For intFila = 1 To chtGraf.object.SeriesCollection.Count chtGraf.object.SeriesCollection(intFila).ApplyDataLabels _ Type:=cte_XLDATA_LABELS_SHOW_VALUE, _ AutoText:=True, LegendKey:=False Next End If Set rs = Nothing End Sub ==================================== 48) Truco con la propiedad ItemData (Listbox y Combo) [VB5 , VB6] La propiedad Itemdata puede usarse para guardar un campo clave de una Select (l os cdigos, id's,...) siempre que sea de tipo integer o long. (Si es un campo tex to de un caracter, puedes guardar el codigo ASCII de ese caracter). 'Esta sub rellena la combo y pone las fechas por defecto en los dtPicker (dtpDes de, dtpHasta) 'Constantes usadas: 'Const cteIGNORAR_EVENTO = ">:-(" 'sirve para evitar que un evento no se ejecut e si no interesa. Para eso la 'primera linea de ese evento (sin contar los DIM) debe ser If (nombre_co ntrol.Tag <> "") Then Exit Sub 'esto es un as en la manga bastante util. Donde mas lo uso es para evita r que el evento Click y/o el Change se 'ejecuten si no me interesa (ej: mientras se rellena una lista o una com bo) 'cnn es una variable global definida de esta forma: ' Dim cnn as New ADODB.Connection Private Sub ValoresPorDefecto_Tab2() Dim rs As New ADODB.Recordset Dim strSQL As String '----------------------------------'== fechas por defecto == dtpHasta.Value = CDate(Year(Date) & "/" & Month(Date) & "/01") dtpDesde.Value = DateAdd("m", -1, dtpHasta.Value) 'dia 1 del mes pasado dtpHasta.Value = dtpHasta.Value - 1 'ultimo dia del mes pasado '== Crea las SQL == 'Todos los registros de la tabla "PERSONAL" ordenados por nombre strSQL = "select pe.idpersonal, pe.nombre from personal pe order by pe.nombre " rs.Open strSQL, cnn 'Abre la conexion cmbPersonal.Tag = cteIGNORAR_EVENTO Do While Not rs.EOF cmbPersonal.AddItem Trim(rs.Fields("nombre")) 'rellena la lista... 'el codigo se mete en el itemdata. si VB tuviese las combos del 'Access, se podria usar una combo de dos columnas y seria mas comodo ;-)

cmbPersonal.ItemData(cmbPersonal.ListCount - 1) = rs.Fields("idpersonal") rs.MoveNext 'pasa al siguiente Loop '---rs.Close Set rs = Nothing End Sub Despues de rellenar la combo en otra parte del programa (por ej, en una funcin) p uedes hacer esto otro: 'esta funcion te devuelve una cadena con el comando SQL que se va a ejecutar ' en otra parte del programa. Public Function Generar_SQL ( ) As String Dim strSQL as String 'comando devuelto por la funcion Dim strCod as String 'El codigo (sacado de la propiedad ItemData) Dim strDesde as String 'fecha con formato SQL Server (sacada de un dtPicker) Dim strHasta as String 'fecha con formato SQL Server (sacada de un dtPicker ) If (cmbPersonal.ListIndex <> -1) Then strCod = cmbPersonal.ItemData(cmbPersonal.ListIndex) 'Tenemos el codigo :-) strDesde = " convert(DateTime, '" & Format(dtpDesde.Value, "mm/dd/yyyy") & " ') " strHasta = " convert(DateTime, '" & Format(dtpHasta.Value, "mm/dd/yyyy") & " ') " 'los saltos de linea (vbCrlf) se ponen por motivos practicos. Compruebalo 'ejecutando " ? strSQL" (sin las comillas) en la ventana inmediata strSQL = "select pt.id_proyecto [ID_PRJ], pr.nombre [NOM_PRJ], " & vbCrLf & _ "pt.id_personal [ID_PER], pe.nombre [NOM_PER], " & vbCrLf & _ "count(*) [NUM_DIAS]" & vbCrLf & _ "from partestrabajo pt" & vbCrLf & _ "inner join personal pe on pt.id_personal = pe.idpersonal" & vbCrLf & _ "inner join proyectos pr on pt.id_proyecto = pr.idproyecto" & vbCrL f & _ "Where pt.id_personal = " & strCod & " and " & vbCrLf & _ " pt.fparte between " & strDesde & " and " & strHasta & vbCrLf & _ "group by pt.id_proyecto, pt.id_personal," & vbCrLf & _ " pr.nombre , pe.nombre" & vbCrLf & _ "order by pr.nombre" Else StrSQL = "" End If Generar_SQL = strSQL End Function ==================================== 49) Abrir un fichero de texto sin que salga la ventana 'Convertir archivo' [VBA Word] Uno de los parametros del mtodo Open [de la coleccin Documents] sirve para indicar si aparece la ventana de convertir archivos o no. Ejemplo: Application.Documents.Open FileName:="FICHERO.TXT", ConfirmConversions:=False

(cambia "FICHERO.TXT" por el archivo que quieras abrir)

Potrebbero piacerti anche