Access y VBA
Blog de Access y VBA del Buho


Inicio


Acerca de
Suscríbete al blog

Categorías
General [3] Sindicar categoría
Access con Codigo VBA [15] Sindicar categoría

Archivos
Septiembre 2005 [11]
Agosto 2005 [5]
Junio 2005 [2]

Sindicación (RSS)
Artículos
Comentarios

 


Lanzar un documento desde Access

Otra pregunta muy habitual que se plantea con relativa frecuencia, es la de ¿Como abrir un documento del tipo que sea o simplemente lanzar un ejecutable EXE desde una aplicación de Access?

Primer método: Ejecutables. Orden SHELL

Si lo que queremos lanzar es un ejecutable (Como tal entendemos *.exe *.com y *.bat) podemos utilizar simplemente una simple llamada a la función nativa Shell. Por ejemplo:

Dim Retval

Dim Retval

Retval = Shell( _ 

        "Notepad.exe " & CurrentProject.Path & "documento.txt", _ 

         vbMaximizedFocus)

En este ejemplo, dado que Notepad.exe es un fichero ejecutable del sistema Windows, no hace falta indicar la ruta donde se encuentra. Además observamos como pasamos como parametro, la ruta y el fichero de texto que deseamos abrir y la forma en que queremos que se muestre la venta(vbMaximizedFocus).

Si el ejecutable no está registrado como tal en el sistema Windows, deberíamos pasar la ruta donde se encuentra dicho programa. Por ejemplo:

Shell "C:RutaMifichero.exe"

Algunos ejemplos interesantes de este uso de Shell:

Sub CargaExplorer() 

  'Cargaría en pantalla la carpeta C:Windows 

  Shell "explorer c:windows", vbMaximizedFocus
End Sub

Function EnviaMensaje(Ip As String, mensaje As String) 

  'Esta funcion enviaría a una Ip de la Red local, pasada como parámetro, un 

  'mensaje 

  'que se mostraría en la pantalla del ordenador Remoto. 

  'Para sistemas Windows NT,2000, XP. 

  'Sustituye al propgrama PopPup de Win 98 

  Shell "Net Send " & Ip & " " & mensaje

End Function

Sub TomaHOraFechaServer() 

  'Otro curioso uso de Shell: 

  'Queremos sincronizar la fecha y hora 

  'de nuestro ordenador, con la que realmente 

  'existe y marca nuestro servidor: 

  Shell "net time \Pc_server /yes /set" 

  'Ten presente que el nombre de \Pc_server 

  'es el nombre del servidor de nuestra Red 

  'tal cual es visto bajo la Red local de Windows

End Sub
Sub TransmiteFtp() 

  'Una muy curiosa. 

  'Como enviar comandos FTP desde Access 

  'con el programa FTP del propio Windows. 

  'Utilizamos conjuntamente la orden 

  'Shell que es la que lanza realmente 

  'la orden FTP 

  'En el fichero Ordenes.txt se encuentra 

  'recogidas las acciones que deseo realizar 

  '(Ver un ejemplo del fichero, debajo de este código) 

  Shell ("ftp -s:C:Ordenes.txt")

End Sub

Listado del fichero plano Ordenes.txt

open 216.7.190.133
Usuario
Contraseña
cd Directorii
put c:Fichero.jpg
bye

[Para ver más órdenes FTP, visitar el siguiente enlace:

 http://www.iespana.es/canalhanoi/internet/comandosftp95.htm]

Y...así podríamos ir poniendo una serie de ejemplos interminables del uso de Shell en VBA de Access

Segundo Método: Utilizar la API de Windows

A veces, bien por comodidad, bien por que desconocemos el programa que tiene asociado un determinado tipo de fichero, es conveniente sustituir la nativa Shell, por una sencilla API. Por ejemplo, deseamos lanzar un documento Word, un documento *.snp...o bien, simplemente, abrir otra Mdb. El código de esta API es bien simple:

Option Explicit

'Declara esta API en un modulo

Declare Function Ejecuta Lib  "shell32.dll" Alias "ShellExecuteA" _

(ByVal hWnd As Long, ByVal lpOperation As String, _
 ByVal
 lpFile As String
, _
 ByVal
 lpParameters As String
, _
 ByVal
 lpDirectory As String
, _
 ByVal
 nShowCmd As Long) As Long

'Esto en cualquier formulario...

Sub Prueba() 

  Ejecuta 1, "open", _ 

  "C:Carpetamifichero.mdb", "", "", 1
End Sub

Esta API anterior sirve para lanzar CUALQUIER fichero, del tipo que sea, sin saber a priori el programa ejecutable que tiene asociado. De no existir dicha asociación, simplemente no se ejecutaría nada

Tercer Método: Utilizar FollowHyperlink de VBA

Sub AbreDocumento() 

  If MsgBox("Abrir el documento: C:DocumentosDocumento.doc ¿Si /no?", _ 

      vbYesNo, "Confirmar") = vbYes Then 

    FollowHyperlink "C:DocumentosDocumento.doc" 

  End If
End Sub

Cuarto Método:WSH

Utilizar el método Shell del objeto Windows Scritp Host. En la página de Juan M. Afán de Ribera tienes un claro ejemplo comentado:

http://www.mvp-access.com/juanmafan/wsh/wshrun.htm

Por ErBuho - 5 de Septiembre, 2005, 1:18, Categoría: Access con Codigo VBA
Enlace Permanente | Referencias (0)

Dialogo Guardar Como

He expuesto anteriormente hasta 4 métodos para abrir el diálogo «Abrir Archivo» en Access (Dependiendo de versiones).

Pero bastantes personas desconocen como se abre el diálogo «Guardar como».

En el siguiente ejemplo que te propone el Búho, utilizamos los dos métodos en un caso REAL. Este ejemplo, no es otro, que escoger un fichero de disco duro (Dialogo Abrir) y copiarle a otra ubicación que el usuario escoja, mediante el cuadro «guardar como».

Los dos diálogos, juntos, pero no revueltos.

http://accessbuho.mvps.org/ficheros/guardacomo.zip

Por ErBuho - 31 de Agosto, 2005, 12:55, Categoría: Access con Codigo VBA
Enlace Permanente | Referencias (0)

Serie del disco duro

Hasta no hace mucho, el Búho, o sea yo, aunque conocía la existencia del concepto «serie del disco duro» no tenía las ideas muy claras al respecto de como diferenciar mediante código VBA los «dos» números de serie que conocía.

Hay que distinguir claramente entre los números de serie de un disco duro, si por ejemplo, queremos utilizar ese dato para protección de programas. Un número de serie es el «numero de serie del volumen» número que se asigna automáticamente al formatear una unidad o partición. Este número se genera, como ya he dicho, cuando se formatea una unidad de disco. En el archivo de texto que podrás leer si te bajas el ejemplo que he construido, se explica mejor este funcionamiento. Además de este número de serie del volumen, existe el denominado número de serie FIJO o inalterable, que es el le asigna el fabricante. Este número sí que no varía y es el indicado pues para implementar procesos de protección en nuestras aplicaciones, ya que aunque se formatee dicho disco duro, el número de serie FIJO o de FABRICA, siempre será el mismo.

http://accessbuho.mvps.org/ficheros/seriefisicohd.zip

Por ErBuho - 31 de Agosto, 2005, 12:53, Categoría: General
Enlace Permanente | Referencias (0)

Msgbox especiales

El objeto Msgbox de VBA (Y de VB) es MODAL (Significa que mientras no se cierre, el código que va detrás de él se detiene y también impide manipular o abrir cualquier otro objeto de la ventana Base de datos). Algunas veces este comportamiento puede ser un incoveniente,ya que simplemente deseamos poner un aviso en pantalla, pero que el programa siga su marcha. Otras veces, un Msgbox colocado en cierta parte del codigo, puede bloquear un registro, si el usuario se va a tomar el bocata y se olvida de presionar cualquiera de los botones del Msgbox de VBA

Hay posibilidades de que esto no sea así, teniendo objetos Msgbox alternativos (De igual estética y funcionalidad que el nativo VBA y sin la utilización de formularios «simuladores» de Msgbox) que bien no sean modales o que simplemente estén temporizados y se cierren al X tiempo que nosotros deseemos.

Su implmentación es muy simple y para muestra dos «botónes»:

Ejemplo de Msgbox NO modal

Option Explicit

Private Declare Function MsgboxNoModal Lib "user32" Alias _     "MessageBoxA" (ByVal hwnd As Long, ByVal lpText As String, _

 ByVal lpCaption As String, ByVal wType As Long) As Long

Const MB_ICONASTERISK = &H40&

'Y luego ya se llama asi desde cualquier sitio

Sub EjemploMsgboxNoModal()

  Call MsgboxNoModal(100, "Esto es NO modal.", _ 

      "Ejemplo Msgbox No Modal ", MB_ICONASTERISK)

End Sub

Las otras constantes de los botones e iconos son:

Las otras constantes de los botones e iconos son:

Const MB_DEFBOTON1 = &H0&

Const MB_DEFBOTON1 = &H0&

Const MB_DEFBOTON2 = &H100&

Const MB_DEFBOTON3 = &H200&

Const MB_ICONOASTERISCO = &H40&

Const MB_ICONOEXCLAMACION = &H30&

Const MB_ICONOHAND = &H10&

Const MB_ICONOINFORMACION = MB_ICONOASTERISCO

Const MB_ICONOPREGUNTA = &H20&

Const MB_ICONOSTOP = MB_ICONOHAND

Const MB_OK = &H0&

Const MB_OKCANCEL = &H1&

Const MB_YESNO = &H4&

Const MB_YESNOCANCEL = &H3&

Const MB_ABORTRETRYIGNORE = &H2&

Const MB_RETRYCANCEL = &H5&

Ejemplo de Msgbox Temporizado

'Especial para los usuarios despistados

'*********** Código ***************

'

' msgboxTemporal

'

' Rutina que demuestra el uso del

' método PopUp del objeto wshShell

' Nos da la posibilidad de estable-

' cer un tiempo de duración en su

' segundo argumento. Por lo demás

' es casi igual que el MsgBox (así

' como el uso de sus constantes vb)

' Autor: Juan M. Afán de Ribera

' Fecha: Junio 2003

'

Sub msgboxTemporal() 

  Dim wShell As Object 'New wshShell 

  Dim Respuesta As Integer 

  Set wShell = CreateObject("WScript.Shell") 

  Respuesta = wShell.PopUp("Estaré abierto 5 segundos", _ 

      5, "Método wshShell.Popup", vbYesNo + vbInformation) 

  Select Case Respuesta

    Case -1: MsgBox "No has apretado ningún botón"

    Case vbYes: MsgBox "Has apretado el botón ""Sí"" "

    Case vbNo: MsgBox "Has apretado el botón ""No"" "

  End Select 

  Set wShell = Nothing 

End Sub

'********* Fin código *************

Y me falta uno muy chulo. Pruebale:

Y me falta uno muy chulo. Pruebale:

EJEMPLO MSGBOX ESPECIAL

Dim Respuesta As Integer

Respuesta = Eval("MsgBox('Atención: Este registro no existe' " & _ 

    "& chr(13) & chr(10) & " & _ 

    "'Confirme su decisión de dar de alta este nuevo registro@" & _ 

    "¿Desea crear este nuevo registro?@',4,'Aviso')")

If Respuesta = 6 Then 

  'Codigo para crear

End If

Este último Msgbox que acabas de ver es un tanto especial, pues pone en negrita parte del texto. Chulo...¿Verdad?

Juan Amador tambien ha realizado una aplicacion MDE que podrás referenciar en tus aplicaciones de Access para poner Msgbox personalizados. Puedes decargarte el fichero (Y leer sus instrucciones de uso) en esta dirección:
http://www.geocities.com/famaads/jmmsgbox/index.html
O bien, desde este propio foro, en elsiguiente enlace:
www.mvp-access.com/buho/ficheros/jmmsgbox.zip
! Gracias Juan !

Y ya para rizar el rizo e interaccionar con el objeto nativo Msgbox de Visual Basic y de VBA para access, deberías visitar este enlace. Podrás poner iconos a los Msgbos,cambiar el texto de los botones etc etc. No estoy hablando de crearte un formulario que simule un Msgbox, te estoy hablando del propio MSGBOX....
Pulsa AQUI

Por ErBuho - 31 de Agosto, 2005, 12:50, Categoría: Access con Codigo VBA
Enlace Permanente | Referencias (0)

Cuadro Dialogo Abrir Archivo

Esta pregunta se suele repetir con cierta frecuencia en este tipo de foros: ¿Como abrir el cuadro de diálogo abrir-escoger Archivo?.

Normalmente las respuestas citan la ya archi-conocida llamada a la API para este menester. Quizá lo que mucha gente desconozca es que existen más métodos para hacer lo mismo, incluso, con más prestaciones.

En el siguiente enlace tienes los métodos que el Búho ha captado para abrir el mencionado cuadro de diálogo. Ojo a la versión de Access que tienes (En el enlace, lo explico):

http://www.retena.es/personales/hualde.retena/access/abrirficherometodos.txt

Además de todo esto, Juan M. Afán de Ribera ha creado un excelente codigo con todo esto, que podrás visitar en el siguiente enlace. NO TE LE PIERDAS!!!!
http://www.mvp-access.com/juanmafan/descargas/filedialog.htm

Por ErBuho - 31 de Agosto, 2005, 12:49, Categoría: Access con Codigo VBA
Enlace Permanente | Referencias (0)

InputBox muy especial

El objeto InputBox es una herramienta muy útil a la hora de interaccionar con el usuario en nuestros programas. Pero está muy limitado en lo que se refiere a sectorizar las entradas que el usuario puede escribir en dicho cuadro de diálogo.

Juan M. Afán de Ribera ha creado una interaccion entre API e Inputbox, que entre otras cosas, permite:

  • Mostrar caracteres tipo entrada de contraseñas
  • Convertir los caracteres introducidos a minúsculas
  • Convertir los caracteres introducidos a mayúsculas
  • Permitir sólo introducción de números
  • Limitar el número de caracteres a introducir

Aquí tienes este excelente código:

http://www.mvp-access.com/juanmafan/descargas/inputboxex.htm

Por ErBuho - 30 de Agosto, 2005, 16:41, Categoría: General
Enlace Permanente | Referencias (0)

Nivel Seguridad en Access 2003

Por Juan Afan de Ribera (MVP Microsoft Access)

Pregunta : Se cómo deshabilitar las advertencias de seguridad que aparecen al iniciar una base de datos en Access 2003, pero me gustaría saber si ésto se puede hacer utilizando código.
Respuesta : Sí, a través de código se pueden también habilitar/deshabilitar las advertencias de seguridad de Access 2003. Pero para hacerlo, tenemos que utilizar o bien Scripting o bien funciones del API para leer y escribir en el registro de Windows.

En este caso, he preferido implementarlo a través del API de Windows.

Las funciones que he construído son las siguientes:

Funciones Nivel Seguridad:

Leer/escribir nivel seguridad de macros y código

Nombre de función Descripción Valor devuelto
GetSecurityLevel Función que devuelve el nivel de seguridad para macros y código de una base de datos Cualquiera de los valores señalados en el cuadro "Valores nivel de seguridad para macros y código"
SetSecurityLevel Función que establece el nivel de seguridad para macros y código de una base de datos. Su único argumento (Level) puede ser cualquiera de los valores que aparecen en el cuadro "Valores del nivel de seguridad de macros y código" True en caso de tener éxito y False en caso contrario.

Valores nivel de seguridad para macros y código

Constante Valor Descripción
Low 1 Nivel bajo. No ofrece protección contra macros inseguras.
Medium 2 Nivel medio. Se puede elegir entre ejecutar o no ejecutar macros que podrían no ser seguras.
High 3 Nivel alto. Sólo se ejecutarán macros firmadas digitalmente. Las macros sin esta característica se deshabilitan automáticamente
Funciones Bloqueo de expresiones

Leer/escribir nivel de bloqueo de expresiones

Nombre de función Descripción Valor devuelto
GetSandBoxMode Función que devuelve el nivel de bloqueo de expresiones consideradas no seguras. Cualquiera de los valores señalados en el cuadro "Valores nivel de bloqueo en expresiones no seguras"
SetSandBoxMode Función que establece el nivel de bloqueo de expresiones consideradas no seguras. Su único argumento (SandBoxMode) puede ser cualquiera de los valores que aparecen en el cuadro "Valores nivel de bloqueo en expresiones no seguras" True si la función tuvo éxito y False en caso contrario.

Valores nivel de bloqueo en expresiones no seguras

Constante Valor Descripción
Disabled 0 Deshabilitado. No existe ningún tipo de bloqueo en expresiones no seguras.
OnlyAccessApps 1 Sólo habilitado para aplicaciones de bases de datos de Access.
NonAccessApps 2 Habilitado para todo tipo de aplicaciones que no sean de Access
Enabled 3 Habilitado para todo tipo de aplicaciones.
En este enlace podrás encontrar más información sobre este tema, así como una lista de las expresiones de Visual Basic consideradas no seguras.

Ejemplos de uso:
' obtener el nivel de seguridad
NivelSeguridad = GetSecurityLevel
    
' obtener el nivel de bloqueo
NivelBloqueo = GetSandBoxMode
    
' establecer el nivel de seguridad
If SetSecurityLevel(Low) = True Then
    MsgBox "Se ha establecido un nivel de seguridad bajo"
End If
    
' establece el nivel de bloqueo
If SetSandBoxMode(NonAccessApps) = True Then
    MsgBox "Se ha establecido un nivel de bloqueo estándar"
End If
Este código en un módulo estandar
'---------------------------------------------------------
'
' GetSecurityLevel
' SetSecurityLevel
' GetSandBoxMode
' SetSandBoxMode
'
' Código escrito originalmente por Juan M Afán de Ribera.
' Estás autorizado a utilizarlo dentro de una aplicación
' siempre que esta nota de autor permanezca inalterada.
' En el caso de querer publicarlo en una página Web,
' por favor, contactar con el autor en
'
'     accessvbafaq@ya.com
'
' Este código se brinda por cortesía de
' Juan M. Afán de Ribera
'
' -------------------------------------------------------
'
' Enumeración para los valores de seguridad
Public Enum SecurityLevelEnum
    Low = 1&
    Medium
    High
End Enum
' Enumeración para los valores del bloqueo de expresiones
' no seguras
Public Enum SandBoxModeEnum
    Disabled = 0&
    OnlyAccessApps
    NonAccessApps
    Enabled
End Enum

' función que permite abrir una clave de registro
' con nivel de permisos
Private Declare Function RegOpenKeyEx Lib "advapi32.dll" _
                Alias "RegOpenKeyExA" _
                (ByVal hKey As Long, _
                ByVal lpSubKey As String, _
                ByVal Reserved As Long, _
                ByVal samDesired As Long, _
                phkResult As Long) As Long
               
' función que permite crear una clave de registro
' con nivel de permisos
Private Declare Function RegCreateKeyEx Lib "advapi32.dll" _
                Alias "RegCreateKeyExA" _
                (ByVal hKey As Long, _
                ByVal lpSubKey As String, _
                ByVal Reserved As Long, _
                ByVal lpClass As String, _
                ByVal dwOptions As Long, _
                ByVal samDesired As Long, _
                lpSecurityAttributes As Any, _
                phkResult As Long, _
                lpdwDisposition As Long) As Long
                
' función que permite leer el valor de una clave de registro
Private Declare Function RegQueryValueEx Lib "advapi32.dll" _
                Alias "RegQueryValueExA" _
                (ByVal hKey As Long, _
                ByVal lpValueName As String, _
                ByVal lpReserved As Long, _
                lpType As Long, _
                lpData As Any, _
                lpcbData As Long) As Long

' función para establecer el valor de una clave de registro
Private Declare Function RegSetValueEx Lib "advapi32.dll" _
                Alias "RegSetValueExA" _
                (ByVal hKey As Long, _
                ByVal lpValueName As String, _
                ByVal Reserved As Long, _
                ByVal dwType As Long, _
                lpData As Any, _
                ByVal cbData As Long) As Long
                
' función para cerrar un manipulador de una clave de registro
Private Declare Function RegCloseKey Lib "advapi32.dll" _
                (ByVal hKey As Long) As Long
                
' constantes de claves predefinidas
Private Const HKEY_CURRENT_USER = &H80000001
Private Const HKEY_LOCAL_MACHINE = &H80000002
' constante para que una clave de registro creada
' sea almacenada y no sea borrada entre sesiones
Private Const REG_OPTION_NON_VOLATILE = 0&
' constante de permiso de lectura
Private Const KEY_QUERY_VALUE = &H1
' constante de permiso de escritura
Private Const KEY_SET_VALUE = &H2
' constante que indica éxito al acceder a una clave
Private Const ERROR_SUCCESS = 0&
' constante con el valor "REG_DWORD" (tipo de datos
' utilizados en el registro)
Private Const REG_DWORD = &H4

' Función que obtiene el nivel de seguridad para macros o código
Public Function GetSecurityLevel() As SecurityLevelEnum
    GetSecurityLevel = GetKeyValue("Level")
End Function

' Función que establece el nivel de seguridad para macros o código
Public Function SetSecurityLevel(ByVal Level As SecurityLevelEnum) As Boolean
    ' el parámetro Level no puede ser menor que Low (1)
    ' ni mayor que High (3)
    If Level < Low Or Level > High Then Exit Function
    SetSecurityLevel = SetKeyValue("Level", Level)
End Function

' Función que obtiene el nivel de evaluación de expresiones no seguras
Public Function GetSandBoxMode() As SandBoxModeEnum
    GetSandBoxMode = GetKeyValue("SandBoxMode")
End Function

' Función que establece el nivel de evaluación de expresiones no seguras
Public Function SetSandBoxMode(ByVal Level As SandBoxModeEnum) As Boolean
    ' el parámetro Level no puede ser menor que Disabled (0)
    ' ni mayor que Enabled (3)
    If Level < Disabled Or Level > Enabled Then Exit Function
    SetSandBoxMode = SetKeyValue("SandBoxMode", Level)
End Function

' Función que obtiene valores del registro sobre seguridad y bloqueo de
' expresiones no seguras. El parámetro ValueName hace referencia al valor
' del registro que queremos leer
Private Function GetKeyValue(ValueName As String)
Dim sKey As String
Dim hKey As Long
Dim RegKey As Long
Dim Level As Long
    
    Select Case ValueName
        ' El valor del registro "Level" hace referencia a la clave
        ' del registro relativo al nivel de seguridad
        Case "Level"
            ' formamos la clave de registro donde se buscará
            sKey = "Software\Microsoft\Office\11.0\Access\Security"
            RegKey = HKEY_CURRENT_USER
        ' El valor del registro "SandBoxMode" hace referencia a
        ' la clave de registro relativo al bloqueo de expresiones
        ' no seguras
        Case "SandBoxMode"
            ' formamos la clave de registro donde se buscará
            sKey = "SOFTWARE\Microsoft\Jet\4.0\Engines"
            RegKey = HKEY_LOCAL_MACHINE
    End Select
    
    ' si se puede abrir la clave de registro con permisos
    ' de lectura (KEY_QUERY_VALUE)
    If RegOpenKeyEx( _
                    RegKey, _
                    sKey, _
                    0&, _
                    KEY_QUERY_VALUE, _
                    hKey) = ERROR_SUCCESS Then
        ' si se puede leer el valor de la clave de registro
        ' "Level" o "SandBoxMode" según corresponda
        If RegQueryValueEx( _
                           hKey, _
                           ValueName, _
                           0&, _
                           REG_DWORD, _
                           Level, _
                           Len(Level)) = ERROR_SUCCESS Then
            ' devolvemos el valor
            GetKeyValue = Level
        End If
        ' cerramos el manipulador de la clave de registro
        ' que hemos abierto
        Call RegCloseKey(hKey)
    End If

End Function

' Función que establece valores del registro sobre seguridad y bloqueo de
' expresiones no seguras. El parámetro ValueName hace referencia al valor
' del registro que queremos leer
Private Function SetKeyValue(ValueName As String, Level As Long) As Boolean
Dim sKey As String
Dim hKey As Long
Dim valRet As Long
Dim RegKey As Long

    Select Case ValueName
        ' El valor del registro "Level" hace referencia a la clave
        ' del registro relativo al nivel de seguridad
        Case "Level"
            ' si Access 2003 no está instalado salimos de la función
            If Not Acc03Installed Then Exit Function
            ' formamos la clave de registro donde se buscará
            sKey = "Software\Microsoft\Office\11.0\Access\Security"
            RegKey = HKEY_CURRENT_USER
        ' El valor del registro "SandBoxMode" hace referencia a
        ' la clave de registro relativo al bloqueo de expresiones
        ' no seguras
        Case "SandBoxMode"
            ' formamos la clave de registro donde se buscará
            sKey = "SOFTWARE\Microsoft\Jet\4.0\Engines"
            RegKey = HKEY_LOCAL_MACHINE
    End Select
    
    ' si NO se puede abrir la clave de registro con permisos
    ' de escritura (KEY_SET_VALUE)
    If RegOpenKeyEx( _
                    RegKey, _
                    sKey, _
                    0&, _
                    KEY_SET_VALUE, _
                    hKey) <> ERROR_SUCCESS Then
        ' querrá decir que la clave no existe, así que la
        ' creamos del tipo "REG_DWORD", para que se almacene
        ' "REG_OPTION_NON_VOLATILE" y con permisos de escritura
        ' KEY_SET_VALUE
        ' si no se puede crear...
        If RegCreateKeyEx( _
                          RegKey, _
                          sKey, _
                          0&, _
                          "REG_DWORD", _
                          REG_OPTION_NON_VOLATILE, _
                          KEY_SET_VALUE, _
                          ByVal 0&, _
                          hKey, _
                          valRet) <> ERROR_SUCCESS Then
            ' ... salimos de la función
            Exit Function
        End If
    End If
    ' se llegamos aquí es que la clave ya existe
    ' si podemos establecer el valor que queremos...
    If RegSetValueEx( _
                     hKey, _
                     ValueName, _
                     0&, _
                     REG_DWORD, _
                     Level, _
                     Len(Level)) = ERROR_SUCCESS Then
        ' ... hemos tenido éxito
        SetKeyValue = True
    End If
    ' cerrramos el manipulador de la clave de registro
    Call RegCloseKey(hKey)
    
End Function

' función que comprueba en el registro si Access 2003
' está instalado en el sistema
Private Function Acc03Installed() As Boolean
Dim hKey As Long

    ' si podemos abrir esta clave del registro
    If RegOpenKeyEx( _
                    HKEY_CURRENT_USER, _
                    "Software\Microsoft\Office\11.0\Access", _
                    0&, _
                    KEY_QUERY_VALUE, _
                    hKey) = ERROR_SUCCESS Then
        ' querrá decir que Access 2003 está instalado
        Acc03Installed = True
        ' cerramos el manipulador de la clave de registro
        Call RegCloseKey(hKey)
    End If
    
End Function
'---------------------------------------------------------

Ejemplos:

MsAccessSecurity.zip

Por ErBuho - 27 de Junio, 2005, 9:17, Categoría: Access con Codigo VBA
Enlace Permanente | Referencias (0)

Sockets de Windows y Winsock de VB

Aquí va un resumen sobre este mundo maravilloso de las comunicaciones TCP/IP  a través de Access-VBA y Visual Basic (Bueno, en realidad, hablamos un poco de todo):

*************************************************************************
Aunque parezca un ROLLO leetelo, por favor...te despejaran muchas dudas..
*************************************************************************

Historia

Todos, alguna vez, nos hemos encontrado con la desagradable sorpresa de que al instertar
un control de Visual Basic en nuestros formularios de Access, en nuestro equipo ha funcionado
bien, sin embrago en el equipo cliente no ha funcionado. Esto ha podido ser debido a varias causas.
La primera es que dicho control no exista en el equipo cliente.
La segunda, que aún existiendo, es de una version inferior.
A la postre, al correr dicha aplicacion no va a funcionar, dando desagradables mensajes de error.

Pues esto te puede ocurrir con el control Winsock de VB, que como bien sabrás es el encargado
de programar muchas aplicaciones de comunicaciones (Casi todas las que te puedes imaginar).

Dudas como estas:

1) Si yo hago un ejemplo en Access con MI control WInsock, con la version que tengo en mi ordenador. Y luego preparo un paquete en Visual Basic, con un formulario «tonto» donde esté metido dicho control.
SI el usuario instala el paquete de Visual Basic (Que en realidad solo deberá servir en teoria para copiar y registrar el control en el ordenador cliente)...
¿Aseguro que de esta forma el control Winsock insertado en el formulario de Access funcione sin problemas?
En teoría debería funcionar, pues para eso, con el paquete de VB completo ya he registrado dicho control en el ordenador cliente. No lo acabo de tener claro si SI o si NO

Respuesta:

Sí, sería una manera de hacerlo funcionar, pero habría algunas más. La manera más sencilla es un pequeño “paquete” que incluya el archivo OCX y un archivo BAT (ó CMD para WinNT/2000/XP) con algo así como:

@ECHO OFF
COPY MSWINSCK.OCX C:\WINNT\SYSTEM32 /V
C:\WINNT\SYSTEM32\REGSVR32.EXE C:\WINNT\SYSTEM32\MSWINSCK.OCX

Como ves, eso copiaría el OCX a la carpeta SYSTEM y posteriormente lo registraría en el sistema. Éste método tiene un pequeño problema, y es que MSWINSCK.OCX tiene dependencias con los siguientes archivos:

WSOCK32.DLL
WS2_32.DLL
KERNEL32.DLL
USER32.DLL
OLE32.DLL
ADVAPI32.DLL
OLEAUT32.DLL
GDI32.DLL

Los 6 últimos deberían estar presentes en cualquier Windows, pero sobre los dos primeros tengo mis dudas:
No podría asegurar al 100% que estén presentes en cualquier instalación de Windows.
Vamos, que no estaría de más agregarlos al paquete.

Otra opción es la que mencionabas: crear un programita de instalación con PDW
(Asistente para empaquetado y distribución de Visual Basic);
Creo que es una buena solución, ya que el programa busca automáticamente las dependencias necesarias pero recuerda que tampoco haría falta incluir la aplicación de Visual Basic en la distribución (puedes eliminar el archivo EXE del asistente, creo recordar que en la penúltima pantalla).
Así no se le instalaría al usuario nada que pueda confundirle. De todos modos, yo no usaría el Asistente para empaquetado y distribución de Visual Basic, sino otro instalador como Setup Factory (el que siempre uso yo) o InstallShield.
Éstos instaladores te permiten definir con mucha más precisión el proceso de instalación, con lo que podrías crear una instalador exclusivo para el archivo MSWINSCK.OCX
(es decir, que no tendrías que hacer la aplicación de Visual Basic ni instalársela al usuario).
Además, puedes definir las pantallas de la instalación, de manera que podrías hacer un instalador “silencioso”

Otra opción, y ya que la aplicación “final” será Access es la que me parece más elegante: agregar una tabla oculta a tu base de datos, con un campo BLOB con un único registro, donde subirías el archivo MSWINSCK.OCX.
Al iniciar tu aplicación Access, descargarías el archivo del campo BLOB a la carpeta SYSTEM del usuario y lo registrarías llamando a su DllRegisterServer
(API incluida en todas las librerías ActiveX que registra el OCX en el sistema, el equivalente a hacerlo tu “a mano”con REGSVR32.EXE). Si agregas alguna comprobación (como que el archivo ya exista o sus clases COM ya estén registradas, por ejemplo, capturando el error producido si no se puede crear alguna de ellas)  puedes hacer que éste proceso sólo se haga la primera vez. Completamente silencioso y todo incluido en el MDB.
Muy elegante ;-)

2)Pero bueno, eso es lo de menos, por lo que te pregunto a continuacion.  Aqui quería llegar yo..¿Que significa realmente esto?
¿Que el propio Windows, tengas o no instalado el control Winsock de Microsoft, tiene una API para simular dicho control? ¿O es que en realidad, el control Winsock de Micorosft es un mero intermediario  entre el programador de Visual Basic y dicha API de Windows y de esta forma facilitar la programacion? Vamos, resumiendo, que si el control Winsock no le hubiera fabricado Microsoft, deberiamos utilizar las APIS del propio windows para resolver estos temas con Sockets???

Respuesta:
----------
Efectivamente; el control OCX Winsock de Visual Basic no es más que una encapsulación, un wrapper (un envoltorio que hace más fácil e intuitivo su uso)de las APIs de Windows Sockets
(que estás “metidas” en WSOCK32.DLL y WS2_32.DLL).
Es decir, MSWINSCK.OCX no es más que una librería COM, con interfaz gráfica, que contiene objetos con propiedades y métodos que hacen más sencillo el uso de éstas APIs (pero internamente, en su código fuente, se hacen las llamadas “normales” a éstas APIs)
Por ejemplo la mayoría de programas de Visual C++ trabajan así: usan directamente las funciones API en lugar de incluir OCX, minimizando así las dependencias del ejecutable final
(aunque MFC, la librería de clases de Visual C++, incluye clases que encapsulan también éstas funciones, haciendo más sencillo su uso y agregando sólo la dependencia a MFC42.DLL)
El código de WinsockApi.zip hace precisamente eso: usa las APIs de WSOCK32.DLL y WS2_32.DLL en lugar de los objetos del OCX. Así, no es necesario el archivo MSWINSCK.OCX instalado y registrado en la máquina, ya que se invocan directamente a las APIs (y esto funciona en cualquier Windows). De todos modos, sigo sin estar completamente seguro de que WSOCK32.DLL y WS2_32.DLL vengan incluidas en cualquier instalación de Windows
(mi duda viene, por ejemplo, si no instalas ningún componente de red de Windows); prometo investigarte esto con más profundidad, pero puedes estar tranquilo: el 99,999% de los ordenadores donde lo pruebes, funcionará perfectamente (y si mis dudas son infundadas, que es muy probable, en el 100%)

Apunte de Ricardo Hernandez sobre este ultimo párrafo:
«[Los Windows Sockets 2 están incorporados de "serie" en w2000, wxp y creo que tb en W98 y Wme. Realmente, tampoco me preocupa mucho el tema. El tcp/ip se instala por defecto desde hace algún tiempo.]»»

Bien...ante estas explicaciones y las recomendaciones de Ricardo Hernandez, el Buho localizó un código donde se simulaba el control Winsock de Microft, pero a través de API.
Consta de un modulo de Clase y de un módulo normal. La página donde busque la información (Si es que aún funciona) es:

            http://www.vbip.com/winsock-api/csocket-class/csocket-class-01.asp

Aquí hay dos opciones (Yo empleé las dos) de crearnos un CLON del control Winsock a través de API.

La primera sería incluir el modulo de clase y el modulo estandar en nuestras aplicaciones y de esta forma poder funcionar sin problemas.(En este ZIP se incluyen los modulos originales del ejemplo, sin retocar por mi)En este sentido, Ricardo Hernandez comenta lo siguiente:

««Comentarte una ventaja que a mi juicio es muy importante: Si yo incluyo el código fuente de la clase, dejaría de preocuparme por referencias, registros de ocx/dll, etc. Eliminamos componentes externos al exe/mdb  que afecten al funcionamiento de nuestro programa.
Parece una tontería, pero cuando distribuyes una aplicación no tienes control sobre el entorno de su
ejecución: sistema operativo, versiones de office, parches, controles activeX, ... Por mucho que digas y recomiendes los clientes hacen lo que les parece
»».

El entorno hardware/software debe reunir unos requisitos para ejecutar nuestra aplicación. Estamos de acuerdo en que si este entorno no cumple dichos requisitos, nadie puede responsabilizarnos porque el programa no funcione. Pero siempre te encuentras situaciones en las que por h o por b tienes que salir del paso como puedas.

Otro argumento a favor de la inclusión del código fuente es la seguridad incorporada en los S.O 2000 y xp. Estamos tan acostumbrados a trabajar como administradores que se nos olvida un punto clave.  En muchas redes los usuarios no son administradores. Esto es muy importante porque impedirá registrar dll's y ocx's (suponiendo que los administradores no hayan recortado todavía más a los usuarios).»»

Y la segunda sería crear en Visual Basic una DLL Activex que encapsulara dichos modulos.
Con esta DLL ya podríamos trabajar en nuestras aplicaciones de Access, sin más que referenciar dicha DLL en el menú Referencias de nuestro proyecto VBA.(Es el ejemplo que te has bajado)

Ahora bien...aquí el búho se planteó otra duda mas:

Acabo de decir que la DLL de este ejemplo está hecha en Visual Basic. Esto implica que para que funcione en el ordenador cliente, se necesita el Runtime de Visual Basic.
¿Y que es eso del Runtime de Visual Basic?
Pues un conjunto de ficheros que nos aseguren que cualquier DLL o programa de Visual Basic pueda correr en ordenadores donde no esté instalado el entorno de programacion de Visual Basic.

En este sentido,cuando estaba contruyendo yo  esta DLL clon del Winsock de Windows, me surgió esta duda precisamente.
Ricardo Hernandez, de un plumazo, se encargó de despejarmela:

RUNTIME DE VISUAL BASIC

En el foro, en una conversacion entre Emilio Sancha y yo, le comentaba que probara este ejemplo y le decia literalmente:
  «ojo que la DLL está hecha en Visual Basic y necesitarás el Runtime par que te funcione bien...»

  «No debes tener el VB instalado. El access 2000 (y sus sucesores tambien) instalan todas las
   librerías runtime de VB necesarias. Puedes hacer la prueba cogiendo un exe hecho en Vb y ejecutándolo a pelo en un equipo que tenga el office. Lo que está claro es que la librería debe estar registrada. Si además creas los objetos con "New ...", entonces tb debe estar como referencia. »

 Efectivamente, así es. Ricardo Hernandez se encargó de despejarme esta duda conceptual.

 En resumidas cuentas, tú no tendrás problemas con esta DLL WinSock del Buho hecha en Visual Basic. Correrá perfectamente en cualquier ordenador que tenga Access 2000 o superior.
No obstante, desde estas direcciones podrás bajarte el Runtime completo de Visual basic
(Gratuito y disponible en Microsoft)

Enlace Microsoft:
Para sl SP5
-----------
http://www.microsoft.com/downloads/details.aspx?FamilyID=bf9a24f9-b5c5-48f4-8edd-cdf2d29a79d5&displaylang=en

Para el SP6
-----------
http://www.microsoft.com/downloads/details.aspx?displaylang=es&FamilyID=7b9ba261-7a9c-43e7-9117-f673077ffb3c
(Recomendado)

Y recuerda que los Service Pack que crea Microsoft son acumulativos (Se presupone que si te bajas el SP6 tendrás tambien lo del Sp5)

Dice Microsoft:

VBRun60sp5.exe es un archivo ejecutable autoextraíble que instala las versiones más recientes
de los archivos de tiempo de ejecución de Microsoft Visual Basic, que todas las aplicaciones creadas
con Visual Basic 6.0 necesitan.
Los archivos incluyen las revisiones incluidas en el Service Pack 5 de Visual Studio 6.0.
===============
vbrun60sp6.exe es un archivo ejecutable autoextraíble que instala versiones de los archivos
de tiempo de ejecución de Microsoft Visual Basic necesarios para todas las aplicaciones creadas
con Visual Basic 6.0. Los archivos incluyen las revisiones distribuidas con el Service Pack 6
para Visual Basic 6.0.
===============

Estos Runtimes tambien estan disponibles desde la web del Buho:

Runtime SP5: Enlace Buho: www.mvp-access.com/buho/ficheros/runtimevb6Sp5.zip  (1 Mega)

Runtime SP6: Enlace Buho: www.mvp-access.com/buho/ficheros/runtimevb6Sp6.zip  (1 Mega)


Y para finalizar este tema del Runtime, comentarte que si un programa de Visual Basic (EXE)
incluye ya controles y demas historias, el Runtime no será suficiente: Deberás tener dichos controles instalados y registrados en tu equipo.
Pero bueno, ese es otro tema. La DLLWinsock no incluye nada raro de «eso», simplemente llamadas a la API de Windows.

Pero recuerda...si tienes Access 2000 o superior, no necesitarás este Runtime de Visual Basic.

Otra Historia: Las Referencias.

Cuando  referenciamos, por ejemplo, una DLL, como es el caso de este ejemplo, hay dos formas de hacerlo:
Referenciar de forma implicita y de forma explicita.
La mas conveniente es de forma implicta

Forma implicita
===============
Supongamos esta DLL del Winsock.
En nuestro proyecto de access NO referenciamos en el editor de VBA la DLL. No ponemos absolutamente nada
(Luego verás por qué)

Entonces...¿Como la hacemos?
En este ejemplo, en el encabezado del modulo de clase del formulario
FrmMensaje, podríamos poner:

Dim Winsock1 As Object

es decir, vamos a decir que «nuestro» Winsock (Encapsulado en la Dll) es un objeto.
y luego en el evento Load del form...asignamos:

Set Winsock1=CreateObject("WinsockBuho.ClsBuho")

y eso bastaría para operar con las propiedades y metodos del Winsock de la DLL.
ClsBuho es el modulo de clase con el que ha sido montada la Dll

Forma Explicita
===============
Esta forma es como lo he hecho en este ejemplo. Y aunque decía que no era la mas conveniente
he optado a hacerlo así, para explicarte otro tema importante sobre las Referencias.
Esta forma implica referenciar en Herramientas-> Referencias del editor de VBA la DLL en cuestion
(Caso de este ejemplo).

Si te fijas en el codigo del formulario de ejemplo FrmMensaje, declaro la variable como:

Public WithEvents Winsock1 As ClsBuho

y luego en el Load la asigno como:

Set Winsock1 = New ClsBuho 'Instancio la Clase para hacer uso de ella

Esto tiene una ventaja añadida sobre referenciar de forma implicita. Si tu en el editor de VBA
escribes la palabra Winsock1.  seguida de un punto, se te desplegarán las propiedades y metodos de dicha ClsBuho(Modulo de clase) que forma la DLL.
Esto facilita mucho la programación.
No obstante (Y segun comentaba Ricardo): «« lo mas conveniente en un proyecto es, primero referenciar de forma explicita para «gozar» de esta ventaja de que aparezcan en el editor las propiedades y los metodos y una vez que el tema funcione y esté depurado, borrar la referencia explicita y referenciar de forma implicita.»»

¿Y por que?

Pues muy facil: Por el tema de las referencias ROTAS.

Yo este ejemplo le he montado, como te decía, refereciando de forma Explicita la DLL y además de forma intencionada. Esto implica que en el editor de VBA debo cargar en Herramientas-> Referencias dicha DLL. Y debo cargarla desde una ruta concreta de mi PC.
¿Que pasa cuando alguien se baja este ejemplo y  le ejecuta?
Pues que, como puede depositarle en cualquier sitio, Access no puede encontrar la DLL en cuestión ya que ésta puede estar en otra ruta diferente a la que originalmente yo marqué en mi PC. Resultado: El ejemplo no funciona. Pero esto tambien se puede controlar

Marius, en este sentido, me sacó de otro apuro, ya que si yo en el codigo original «pensaba que ese tema estaba controlado»...si lo estaba, pero de forma incorrecta.
En el modulo «ModEscribeOleDisco» veras las correciones que ha hecho Marius, para controlar este tema. Y creo interesante comentarte lo siguiente.
Yo cuando estaba haciendo pruebas en mi PC con este ejemplo había colocado originalmente el siguiente codigo para controlar el tema de las referencias rotas:

 PEGO
 ====
 Public Function Autoexec()
    Dim Ref As Reference
    Dim RefRota As Reference
    For Each Ref In References

       
            ' referencia rota
            ' veamos si es la dll del buho
           If InStrRev(Ref.Name, "WinsockBuho.dll") <> 0 Then
             MsgBox "Nombre de la Referencia rota:" & Ref.Name & vbCrLf _
                   & "Ruta Origina: " & Ref.FullPath & vbCrLf _
                   & "GUID completo de la Referencia: " & Ref.Guid, vbCritical + vbOKOnly, "Vamos a intentar Regenerarla..."
             Set RefRota = References(Ref.Name)
             References.Remove RefRota 'borramos la referencia
             EscribeRegistra 'esta funcion lo que hace es crear en disco la DLL y registrarla
             'aqui añado la referencia al proyecto
             Application.References.AddFromFile CurrentProject.Path & "\WinsockBuho.dll"
             Exit For
          Else
           'es otra...lo siento...aqui terminanos
           DoCmd.Quit
          End If
        End If
    Next Ref
   
End Function

Esto me funcioba a mi. Pero este codigo NO es correcto. A ver si me explico.
A mi me funcionaba en mis pruebas, ya que la primera vez que registré la DLL se copiaron el el registro de Windows una serie de datos sobre esta DLL: Su nombre, su ruta, su GUID etc.
De tal forma que al seguir haciendo pruebas, cambiando de lugar la DLL o incluso de nombre, efectivamente entraba en ese If Ref.IsBroken Then  y se ejecutaba la rutina de reubicacion/recomposición de la referencia Peeeeeeeeeeeeeeeeeeeeeero...¿Ese codigo funcionaría en un ordenador QUE POR PRIMERA VEZ CORRIERA el ejemplo?
Pues no, fallaría, como muy suavemente me dijo Marius, como una escopeta de feria. (Gracias Marius, yo tamnien te quiero)
¿Por que? Pues muy facil: Dado que en ese PC nunca se había registrado dicha DLL, en el Reg de Windows no habría constancia de ella y por lo tanto (Y leyendo la ayuda de Access lo explica clarisimimante) no se podrían hacer llamadas del tipo
   Ref.Name
   Ref.FullPath

Pego lo que pone la ayuda de Access:
 ««La propiedad IsBroken está disponible sólo mediante Visual Basic y es de sólo lectura.
   El valor predeterminado de la propiedad IsBroken es Falso. La propiedad IsBroken devuelve Verdadero sólo si el objeto Reference ya no apunta a una referencia válida en el Registro.
   Al evaluar la propiedad IsBroken, puede determinar si el archivo asociado a un objeto Reference determinado se ha movido a un directorio diferente o se ha eliminado.
   Si la propiedad IsBroken tiene el valor Verdadero, Microsoft Access genera un error al intentar leer las propiedades Nombre (Name) o FullPath.»»

 Y en efecto...esto es lo que me estaba pasando a mi (La ayuda de Access en ese sentido es imcompleta para no variar)
Es decir...a mi no me daba error dicho codigo anterior, pues ya había constancia en el registro de Windows de dicha Referencia, aunque estuviera rota. Sin embargo en el ordenador de MArius, que jamas habia sido instalada dicha Dll daba error. Quizá habría que complementar un poco mas ese parrafo de la ayuda de Access. Bueno, quizá no, SEGURO !!


   Entonces, la forma de controlar todo esto, la resumió Marius en tres líneas;
 
 « Amo a vé; si hay una ref rota:

   - debes poner vba. delante de aquellas funciones que puedan dar problemas (string, left, y similares)

   - con una ref rota, yo no puedo leer ni el ref.name ni el ref.fullpath

   - no puedo borrar una ref rota, primero la registro, despues la borro y vuelvo a crear la referencia»»

En efecto...Marius Adaptó el anterior codigo que a mi no me fallaba pero a él si (Ya he explicado porque) y lo dejó tal cual lo podrás ver en el ejemplo. Pero lo pego aquí:

    Dim Ref As Reference
    Dim RefRota As Reference
    For Each Ref In References

        If Ref.IsBroken Then
            ' referencia rota
            ' veamos si es la dll del buho
            ' mod *** marius
            If Ref.Guid = "{746570D6-E1EE-44EF-94ED-1D3443EF1CC9}" Then
             MsgBox "Nombre de la Referencia rota: WinsockBuho.dll" & vbCrLf _
                   & "GUID completo de la Referencia: " & Ref.Guid, vbCritical + vbOKOnly, "Vamos a intentar Regenerarla..."
                   '& "Ruta Origina: " & Ref.FullPath & vbCrLf _
             Set RefRota = Ref 'References(Ref.Guid)
             EscribeRegistra
             References.Remove Ref
             Application.References.AddFromFile CurrentProject.Path & "\WinsockBuho.dll"
             Exit For
           
          Else
           'es otra...lo siento...aqui terminanos
           DoCmd.Quit
          End If
        End If
    Next Ref
   
Compara este codigo de Marius que funciona EN TODOS LOS CASOS, con el mío original que solo funcionaba cuandola referencia se habia roto, pero habia sido registrada previamente.

Bueno y dicho esto sobre las Referencias....a otra cosa mariposa


  El proceso se desencadena ASI

 Abres el ejemplo. Se lanza el formulario de Inicio. En este formulario de inicio, lo primero que hago es comprobar el tema de las Referencias (En este caso mi DLL).
Esto lo hago en el modulo «ModEscribeOleDisco».  funcion Autoexec()
Ahí miro si la referencia esta correcta. Si no lo está (bien por que no exista la DLL bien por que haya sido cambiada de ubicacion se procede, primero a escribir la DLL en disco duro, sacandola de un campo OLE de una tabla(La DLl viaja con esta MDB), una vez extraida, se registra y una vez registrada, se anade como referencia, mediante codigo.
Todo esto lo podrás ver perfectamente en el modulo «ModEscribeOleDisco»...este modulo, aparentemente sencillo, es muy potente didacticamente, ya que te puede servir de refencia para muchas cosas: Controlar Referencias, escribir DLL u otros
ficheros a disco duro y que vayan a ser necesarios para tu aplicación access...etc etc etc


 En cuanto a la DLL, poco puedo decirte: Tiene las mismas propiedades, metodos y eventos que el Winsock de Microsoft.
No tienes mas que habilitar el examinador de objetos del ejemplo, escoger dicha DLL y ver todo lo que te he comentado.
En fin...despues de esta larga parrafada (Espero no haberte aburrido) creo que esta dicho casi todo. Entre este rollo que te he soltado y el codigo del ejemplo...espero que esté claro el uso de esta DLL (API) sustitutiva del nativo de Visual Basic Winsock.

El Buho

Ejemplo, codigo fuente etc disponible en:

http://www.mvp-access.com/buho/ficheros/ControlServerAdjuntosDLL.zip



Por ErBuho - 26 de Junio, 2005, 10:45, Categoría: General
Enlace Permanente | Referencias (0)




<<   Abril 2017    
LMMiJVSD
          1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30

Enlaces
eGrupos
ZoomBlog

 

Blog alojado en ZoomBlog.com