Introducción:
Pues eso... que intentando mejorar el acceso a los ficheros INIs me "entretuve" en leer la ayuda del API para 32 bits y vi un par de funciones que... al menos en teoría, sólo servían para el Windows NT... y mira tú por dónde... también sirven para el Windows 98... no las he probado para el Windows 95, así que si lo haces y funciona, me lo cuentas... ¿vale? Gracias.
El código:
El código que te voy a mostrar ahora tiene dos funciones que ya habrás visto en algún otro sitio de mis páginas, son las funciones para leer y escribir en ficheros INIs; pero ahora te voy a dar otras tres que de seguro te interesarán:
Borrar claves o secciones de un fichero INI.
Leer todos las claves y valores de una sección.
Leer todas las secciones.Decirte que de esta última, no viene la declaración del API en el fichero que se incluye con el VB, así que toma nota, porque es interesante.
Las declaraciones de las funciones del API
' '--- Declaraciones para leer ficheros INI --- ' ' Leer todas las secciones de un fichero INI, esto seguramente no funciona en Win95 ' *** Esta función no estaba en las declaraciones del API que se incluye con el VB *** Private Declare Function GetPrivateProfileSectionNames Lib "kernel32" Alias "GetPrivateProfileSectionNamesA" _ (ByVal lpszReturnBuffer As String, ByVal nSize As Long, _ ByVal lpFileName As String) As Long ' Leer una sección completa Private Declare Function GetPrivateProfileSection Lib "kernel32" Alias "GetPrivateProfileSectionA" _ (ByVal lpAppName As String, ByVal lpReturnedString As String, _ ByVal nSize As Long, ByVal lpFileName As String) As Long ' Leer una clave de un fichero INI Private Declare Function GetPrivateProfileString Lib "kernel32" Alias "GetPrivateProfileStringA" _ (ByVal lpApplicationName As String, ByVal lpKeyName As Any, _ ByVal lpDefault As String, ByVal lpReturnedString As String, _ ByVal nSize As Long, ByVal lpFileName As String) As Long ' Escribir una clave de un fichero INI (también para borrar claves y secciones) Private Declare Function WritePrivateProfileString Lib "kernel32" Alias "WritePrivateProfileStringA" _ (ByVal lpApplicationName As String, ByVal lpKeyName As Any, _ ByVal lpString As Any, ByVal lpFileName As String) As LongAhora las funciones y después vendrá un ejemplo de cómo usarlas.
' Private Function IniGet(ByVal lpFileName As String, ByVal lpAppName As String, _ ByVal lpKeyName As String, _ Optional ByVal lpDefault As String = "") As String ' 'Los parámetros son: 'lpFileName: La Aplicación (fichero INI) 'lpAppName: La sección que suele estar entrre corchetes 'lpKeyName: Clave 'lpDefault: Valor opcional que devolverá si no se encuentra la clave. ' Dim LTmp As Long Dim sRetVal As String sRetVal = String$(255, 0) LTmp = GetPrivateProfileString(lpAppName, lpKeyName, lpDefault, sRetVal, Len(sRetVal), lpFileName) If LTmp = 0 Then IniGet = lpDefault Else IniGet = Left(sRetVal, LTmp) End If End Function Private Sub IniWrite(ByVal lpFileName As String, ByVal lpAppName As String, _ ByVal lpKeyName As String, ByVal lpString As String) ' 'Guarda los datos de configuración 'Los parámetros son los mismos que en IniGet 'Siendo lpString el valor a guardar ' Call WritePrivateProfileString(lpAppName, lpKeyName, lpString, lpFileName) End Sub Private Sub IniDelete(ByVal sIniFile As String, ByVal sSection As String, _ Optional ByVal sKey As String = "") ' ' Borrar una clave o entrada de un fichero INI (16/Feb/99) ' Si no se indica sKey, se borrará la sección indicada en sSection ' En otro caso, se supone que es la entrada (clave) lo que se quiere borrar ' If Len(sKey) = 0 Then ' Borrar una sección Call WritePrivateProfileString(sSection, 0&, 0&, sIniFile) Else ' Borrar una entrada Call WritePrivateProfileString(sSection, sKey, 0&, sIniFile) End If End Sub Private Function IniGetSection(ByVal lpFileName As String, _ ByVal lpAppName As String) As Variant ' ' Lee una sección entera de un fichero INI (27/Feb/99) ' ' Usando Collection en lugar de cParrafos y cContenido (06/Mar/99) ' ' Esta función devolverá una colección con cada una de las claves y valores ' que haya en esa sección. ' Parámetros de entrada: ' lpFileName Nombre del fichero INI ' lpAppName Nombre de la sección a leer ' Devuelve: ' Una colección con el Valor y el contenido ' Para leer los datos: ' For i = 1 To tContenidos Step 2 ' sClave = tContenidos(i) ' sValor = tContenidos(i+1) ' Next ' Dim tContenidos As Collection Dim nSize As Long Dim i As Long Dim j As Long Dim sTmp As String Dim sClave As String Dim sValor As String ' El tamaño máximo para Windows 95 sBuffer = String$(32767, Chr$(0)) nSize = GetPrivateProfileSection(lpAppName, sBuffer, Len(sBuffer), lpFileName) If nSize Then Set tContenidos = New Collection ' Cortar la cadena al número de caracteres devueltos sBuffer = Left$(sBuffer, nSize) ' Quitar los vbNullChar extras del final i = InStr(sBuffer, vbNullChar & vbNullChar) If i Then sBuffer = Left$(sBuffer, i - 1) End If ' Cada una de las entradas estará separada por un Chr$(0) Do i = InStr(sBuffer, Chr$(0)) If i Then sTmp = LTrim$(Left$(sBuffer, i - 1)) If Len(sTmp) Then ' Comprobar si tiene el signo igual j = InStr(sTmp, "=") If j Then sClave = Left$(sTmp, j - 1) sValor = LTrim$(Mid$(sTmp, j + 1)) ' Asignar la clave y el valor tContenidos.Add sClave tContenidos.Add sValor End If End If sBuffer = Mid$(sBuffer, i + 1) End If Loop While i ' Por si aún queda algo... If Len(sBuffer) Then j = InStr(sBuffer, "=") If j Then sClave = Left$(sBuffer, j - 1) sValor = LTrim$(Mid$(sBuffer, j + 1)) tContenidos.Add sClave tContenidos.Add sValor End If End If End If Set IniGetSection = tContenidos End Function Private Function IniGetSections(ByVal lpFileName As String) As Variant ' ' Devuelve todas las secciones de un fichero INI (27/Feb/99) ' ' Usando Collection en lugar de cParrafos y cContenido ' ' Esta función devolverá una colección con todas las secciones del fichero ' Parámetros de entrada: ' lpFileName Nombre del fichero INI ' Devuelve: ' Una colección con los nombres de las secciones ' Dim tContenidos As Collection Dim nSize As Long Dim i As Long Dim sTmp As String ' El tamaño máximo para Windows 95 sBuffer = String$(32767, Chr$(0)) ' Esta función del API no está definida en el fichero TXT nSize = GetPrivateProfileSectionNames(sBuffer, Len(sBuffer), lpFileName) If nSize Then ' Crear una colección del tipo cParrafos que es una colección ' con elementos del tipo cContenido Set tContenidos = New Collection ' Cortar la cadena al número de caracteres devueltos sBuffer = Left$(sBuffer, nSize) ' Quitar los vbNullChar extras del final i = InStr(sBuffer, vbNullChar & vbNullChar) If i Then sBuffer = Left$(sBuffer, i - 1) End If ' Cada una de las entradas estará separada por un Chr$(0) Do i = InStr(sBuffer, Chr$(0)) If i Then sTmp = LTrim$(Left$(sBuffer, i - 1)) If Len(sTmp) Then tContenidos.Add sTmp End If sBuffer = Mid$(sBuffer, i + 1) End If Loop While i If Len(sBuffer) Then tContenidos.Add sBuffer End If End If Set IniGetSections = tContenidos End FunctionBueno... eso es todo lo que se necesita para usar esas funciones, en este caso, si te fijas, las funciones son Private, ya que las he "modificado" para usar en un Form directamente, pero si las quieres "encapsular" en una clase o en un módulo BAS, deberías cambiar las declaraciones a Public, pero no las de las funciones del API... esas pueden (y deberían) seguir siendo Privadas.
Del código para usar estas funciones sólo te voy a enseñar parte... el resto te lo imaginas... que con un poco de imaginación seguro que eres capaz de crear el ejemplo para que funcione... je, je... no es mala "leche", es que así te esfuerzas un poco... que os estoy acostumbrando a darlo todo hecho y eso no ayuda demasiado a aprender...
Aquí están los trozos del Form y una imagen de cómo queda en modo de diseño.
El form de prueba' ' Leer todas las secciones del fichero indicado y guardarlas en el cboSecciones Private Sub LeerSecciones() Dim tContenidos As Collection Dim i As Long ' Llenar las secciones de este fichero Set tContenidos = IniGetSections(txtFicIni) If Not tContenidos Is Nothing Then cboSecciones.Clear For i = 1 To tContenidos.Count cboSecciones.AddItem tContenidos(i) Next cboSecciones.ListIndex = 0 txtValor = "" End If End Sub ' Leer las claves de la sección seleccionada Private Sub cboSecciones_Click() ' Mostrar las claves de esta sección Dim tContenidos As Collection Dim i As Long Set tContenidos = IniGetSection(txtFicIni, cboSecciones.Text) If Not tContenidos Is Nothing Then cboClaves.Clear For i = 1 To tContenidos.Count Step 2 cboClaves.AddItem tContenidos(i) Next cboClaves.ListIndex = 0 txtValor = "" End If End Sub Private Sub cmdBorrar_Click(Index As Integer) ' Borrar sección o clave Dim sFicINI As String Dim sSeccion As String Dim sClave As String sFicINI = Trim$(txtFicIni) sSeccion = Trim$(cboSecciones.Text) sClave = Trim$(cboClaves.Text) If Index = 0 Then ' Borrar sección IniDelete sFicINI, sSeccion ' Releer las secciones disponibles LeerSecciones Else ' Borrar clave IniDelete sFicINI, sSeccion, sClave ' Leer las claves de esta sección cboSecciones_Click End If End Sub Private Sub cmdLeer_Click() ' Leer del fichero INI Dim sFicINI As String Dim sSeccion As String Dim sClave As String Dim sValor As String sFicINI = Trim$(txtFicIni) sSeccion = Trim$(cboSecciones) sClave = Trim$(cboClaves.Text) sValor = Trim$(txtValor) txtValor = IniGet(sFicINI, sSeccion, sClave, sValor) End Sub Private Sub cmdAdd_Click() ' Añadir la sección, clave y/o valor Dim sFicINI As String Dim sSeccion As String Dim sClave As String Dim sValor As String sFicINI = Trim$(txtFicIni) sSeccion = Trim$(cboSecciones) sClave = Trim$(cboClaves.Text) sValor = Trim$(txtValor) IniWrite sFicINI, sSeccion, sClave, sValor End SubPues esto es todo... que no es poco... a disfrutar y... a completar el programilla de ejemplo.
Aunque todo sea dicho... te he dejado poco que hacer... pero...
Nos vemos.
GuillermoNota del 14/Sep/2003:
El código aquí mostrado sirve igualmente para VB5 como para VB6, pero en VB6 se podría cambiar el tipo de datos devuelto por las funciones IniGetSection e IniGetSections, para que en lugar de devolver un valor de tipo Variant, devuelva un array de tipo String. En el código que usa el Array de tipo String no existe la función IniDelete, sino que hay dos funciones, una para borrar una clave: IniDeleteKey y otra para borrar una sección: IniDeleteSection.En estos dos ZIPs tienes los dos ejemplos, uno usando Variant y otro usando un Array del tipo String:
Usando Variant: INIVariant.zip 9.62 KB
Usando Array de String: INIArray.zip 13.7 KB