Start / Tipps / VB 5/6-Tipp 0108: INI-Dateien Werte und Felder, erstellen und lesen
 
Startseite Up-/Download Tutorials Club Das Team
Rubriken Foren Bücher Tips 'n Tricks Suche


VB 5/6-Tipp 0108: INI-Dateien Werte und Felder, erstellen und lesen


Optionen eines Programms können zum Beispiel in der Registry gespeichert und beim nächsten Start wieder ausgelesen werden. Um diese eh schon recht überladene Datenbank etwas zu schonen, sollte man die zu sichernden Werte in einer 'Konfigurationsdatei', sprich INI Datei abgelegen. Die Windos-API bietet dafür einige recht komfortable Funktionen, die das Abspeichern und natürlich auch das Laden sowie das Löschen von Schlüsseln und Feldern ermöglichen.

Schwierigkeitsgrad 2 Verwendete API-Aufrufe:
GetPrivateProfileSectionA (GetPrivateProfileSection), GetPrivateProfileStringA (GetPrivateProfileString), WritePrivateProfileSectionA (WritePrivateProfileSection), WritePrivateProfileStringA (WritePrivateProfileString)
Download des Beispielprojektes Download des Beispielprojektes [3,16 KB]
'Dieser Quellcode stammt von http://www.activevb.de
'und kann frei verwendet werden. Für eventuelle Schäden
'wird nicht gehaftet.

'Um Fehler oder Fragen zu klären, nutzen Sie bitte unser Forum.
'Ansonsten viel Spaß und Erfolg mit diesem Source!

'------------- Anfang Projektdatei Project1.vbp -------------
'--------- Anfang Formular "Form1" alias Form1.frm  ---------
' Steuerelement: Rahmensteuerelement "Frame1"
' Steuerelement: Schaltfläche "Command4" auf Frame1
' Steuerelement: Schaltfläche "Command3" auf Frame1
' Steuerelement: Textfeld "Text8" auf Frame1
' Steuerelement: Textfeld "Text7" auf Frame1
' Steuerelement: Schaltfläche "Command1" auf Frame1
' Steuerelement: Textfeld "Text1" auf Frame1
' Steuerelement: Textfeld "Text2" auf Frame1
' Steuerelement: Schaltfläche "Command2" auf Frame1
' Steuerelement: Textfeld "Text3" auf Frame1
' Steuerelement: Textfeld "Text4" auf Frame1
' Steuerelement: Textfeld "Text5" auf Frame1
' Steuerelement: Textfeld "Text6" auf Frame1
' Steuerelement: Listen-Steuerelement "List1" auf Frame1
' Steuerelement: Listen-Steuerelement "List2" auf Frame1
' Steuerelement: Beschriftungsfeld "Label3" auf Frame1
' Steuerelement: Beschriftungsfeld "Label4" auf Frame1
' Steuerelement: Beschriftungsfeld "Label5" auf Frame1

Option Explicit

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 Long
        
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

Private Declare Function WritePrivateProfileSection Lib _
        "kernel32" Alias "WritePrivateProfileSectionA" _
        (ByVal lpAppName As String, ByVal lpString As _
        String, ByVal lpFileName As String) As Long
        
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
        
Dim File$, Field() As String

Private Sub Form_Load()
  Dim X%
    'Pfad der neuen ini-Datei
    File = App.Path & "\Test.ini"
    Frame1.Caption = File
    
    'Textfelder vordefinieren: Schreiben
    Text1.Text = "Section1"
    Text2.Text = "Key1"
    Text3.Text = "Hallo wie gehts?"
    
    'Textfelder vordefinieren: Lesen
    Text5.Text = "Section1"
    Text6.Text = "Key1"
    Text7.Text = ""
    
    Text8.Text = "Section2"
    
    'Feld zuweisen und ausgeben
    Text4.Text = "Section2"
    ReDim Field(0 To 5)
    Field(0) = "Bananen"
    Field(1) = "Gurken"
    Field(2) = "Erdbeeren"
    Field(3) = "Bohnen"
    Field(4) = "Äpfel"
    Field(5) = "Kartoffeln"
    
    For X = 0 To UBound(Field)
      List1.AddItem Field(X)
    Next X
    
    List2.Clear
End Sub

Private Sub Command1_Click()
  'Wert "Key1" schreiben
  Call INISetValue(File, Text1.Text, Text2.Text, Text3.Text)
  
  'Feld schreiben
  Call INISetArray(File, Text4.Text, Field)
End Sub

Private Sub Command2_Click()
  Dim X%, xArray$()
    'Wert "Key1" lesen
    Text7.Text = INIGetValue(File, Text5.Text, Text6.Text)
    
    'Feld lesen
    ReDim xArray(0)
    Call INIGetArray(File, Text8.Text, xArray)
    
    'Feld ausgeben
    List2.Clear
    If UBound(xArray) > 0 Then
      For X = 0 To UBound(xArray) - 1
        List2.AddItem xArray(X)
      Next X
    End If
End Sub

Private Sub Command3_Click()
  Call INIDeleteKey(File, Text5.Text, Text6.Text)
  Call Command2_Click
End Sub

Private Sub Command4_Click()
  Call INIDeleteSection(File, Text5.Text)
  Call INIDeleteSection(File, Text8.Text)
  Call Command2_Click
End Sub

Private Sub INISetValue(ByVal Path$, ByVal Sect$, ByVal Key$, _
                        ByVal Value$)
  Dim Result&
    'Wert schreiben
    Result = WritePrivateProfileString(Sect, Key, Value, Path)
End Sub

Private Function INIGetValue(ByVal Path$, ByVal Sect$, ByVal Key$) _
                             As String
  Dim Result&, Buffer$
    'Wert lesen
    Buffer = Space$(32)
    Result = GetPrivateProfileString(Sect, Key, vbNullString, _
                                     Buffer, Len(Buffer), Path)
    INIGetValue = Left$(Buffer, Result)
End Function

Private Function INISetArray(ByVal Path$, ByVal Sect$, xArray() _
                             As String)
  Dim X%, Buffer$, Result&
    'Feld in einen String mit Trennzeichen Chr$(0) umwandeln
    For X = LBound(xArray) To UBound(xArray)
      Buffer = Buffer & xArray(X) & Chr$(0)
    Next X
    
    'String schreiben
    Buffer = Left$(Buffer, Len(Buffer) - 1)
    Result = WritePrivateProfileSection(Sect, Buffer, Path)
End Function

Private Sub INIGetArray(ByVal Path$, ByVal Sect$, xArray() As String)
  Dim Result&, Buffer$
  Dim l%, p%, z%
    'String lesen
    Buffer = Space(32767)
    Result = GetPrivateProfileSection(Sect, Buffer, Len(Buffer), Path)
    
    Buffer = Left$(Buffer, Result)
    
    If Buffer <> "" Then
      'String mit Trennzeichen Chr$(0) in ein Feld umwandeln
      l = 1
      ReDim xArray(0)
      Do While l < Result
        p = InStr(l, Buffer, Chr$(0))
        If p = 0 Then Exit Do
        
        xArray(z) = Mid$(Buffer, l, p - l)
        z = z + 1
        ReDim Preserve xArray(0 To z)
        l = p + 1
      Loop
    End If
End Sub

Private Sub INIDeleteKey(ByVal Path$, ByVal Sect$, ByVal Key$)
  Call WritePrivateProfileString(Sect, Key, 0&, Path)
End Sub
 
Private Sub INIDeleteSection(ByVal Path$, ByVal Sect$)
  Call WritePrivateProfileString(Sect, 0&, 0&, Path)
End Sub
'---------- Ende Formular "Form1" alias Form1.frm  ----------
'-------------- Ende Projektdatei Project1.vbp --------------
Windows/VB-VersionWin32sWin95Win98WinMEWinNT4Win2000WinXP
VB4
VB5
VB6

Hat dieser Tipp auf Ihrem Betriebsystem und mit Ihrer VB-Version funktioniert?
Ja, funktioniert! Windows-Version:
Nein, funktioniert nicht bei mir! VB-Version:

Ihre Meinung

Falls Sie Fragen zu oder Erfahrungen mit diesem Tipp haben, dann sollten Sie diese hier posten. Für alles weitere melden Sie sich bitte in einem zum Thema passendem Forum.

Falls Sie in ihren Kommentar Quellcode einbinden wollen, verwenden Sie bitte Pseudotags: Quellcode für VB5/VB6 wird durch ein vorangestelltes [code] markiert und durch [/code] abgeschlossen.

Ihr Name:   
Ihre E-Mailadresse:   
 
Bitte folgende Kontrollnummer eingeben: 783
Kontrolle:   
 
Ihre Frage/Ihr Kommentar:
Ja, ich möchte weitere Beiträge per E-Mail erhalten
Von Ralf am 04.04.2009 um 22:47
32 als Wert in Space ist zu klein es muss MAX_PATH rein!
Der Tipp sollte dahingehend optimiert werden, weil längere
Werte werden sonst einfach abgeschnitten.

Private Const MAX_PATH&=255

Private Function INIGetValue(ByVal Path$, ByVal Sect$, ByVal Key$) _
As String
Dim Result&, Buffer$
'Wert lesen
Buffer = Space$(MAX_PATH) 'Der Wert 32 ist zu klein
Result = GetPrivateProfileString(Sect, Key, vbNullString, _
Buffer, Len(Buffer), Path)
INIGetValue = Left$(Buffer, Result)
End Function
Von Robert am 26.02.2009 um 17:11
Wie kann ich das mit einer ProgressBar machen?
Das heißt:
Ich habe ein Programm und während ich in dem Programm arbeite, ändere ich die ProgressBar! Und die letzte Einstellung möchte ich dann speichern, also die, die ich als letztes gemacht habe.
Meinetwegen ist die ProgressBar beim ersten starten auf 2 und beim zweiten Programmstart auf 20. Wie fasse ich das in eine INI-Datei?
Von Reinhold am 17.04.2008 um 07:13
Hallo, der Tip ist super. Leider habe ich einen etwas Probleme damit. Wenn ich eine Sektion mit einem Unterstrich erstelle, schreibt er diesen in die Ini Datei. Ich kann sie aber nicht mehr lesen.

Beispiel:
[Test_78]

Kann mir hier wer helfen?
Von Harald am 06.06.2006 um 12:21
@Sven

cmdCall.Text = INIGetValue(file, "Options", "Call" ) ' Soll Wert von Call lesen: Hansi    
frmRegister.Text2.Text = INIGetValue(file, "Options", "Name") ' Soll Wert von Name lesen: Hans Wurst
Version = INIGetValue(file, "Options","Version") ' Soll Wert von Version auslesen: V 1.01
cmdCode.Text = INIGetValue(file, "Options", "Code") ' Soll Wert von Code aus lesen: 123456789

Von Sven am 04.06.2006 um 17:09
Hallo,

ich wollte auch eine INI-Datei auslesen, die ich vorher angelegt hatte.

INHALT TEST.INI:

[Options]
Call=Hansi
Name=Hans Wurst
Version=V 1.01
Code=123546789
[Land]
Afrika
Amerika
Australien
Asien

Das Programm gibt mir aber nur das Call und die Länder aus.
Den Rest in Options ignoriert es einfach.
Bin ich zu doof oder habe ich da was übersehen?

Der Code dafür lautet bei mir:

Private Sub Form_Load()

Dim OptiKey$
OptiKey$ = ""

Dim file
'Pfad der neuen ini-Datei
file = App.Path & "\CQ.ini"

Dim X%, xArray$()
'Wert "Options" lesen
OptiKey$ = INIGetValue(file, "Call", cmdCall.Text) ' Soll Wert von Call lesen: Hansi
OptiKey$ = INIGetValue(file, "Name", frmRegister.Text2.Text) ' Soll Wert von Name lesen: Hans Wurst
OptiKey$ = INIGetValue(file, "Version", Version) ' Soll Wert von Version auslesen: V 1.01
OptiKey$ = INIGetValue(file, "Code", cmdCode.Text) ' Soll Wert von Code aus lesen: 123456789

'Feld lesen für Länderauswahl
ReDim xArray(0)
Call INIGetArray(file, cmdLand.Text, xArray)

'Feld ausgeben
cmdLand.Clear
If UBound(xArray) > 0 Then
For X = 0 To UBound(xArray) - 1
cmdLand.AddItem xArray(X)
Next X
End If

End Sub
Von shadowcrow am 17.10.2005 um 11:20
Hallo,
ich möchte ein Programm schreiben, dass eine ini-Datei öffnet und in einer von mir vordefinierten Section bei einem bestimmten Key, den Wert ändert und danach die ini umbenennt.
Kann mir da jemand helfen?
Wäre sehr dankbar.
Von Jonathan Haas am 14.06.2005 um 20:45
Die Bufferlänge von 32 Zeichen ist spätestens wenn man Pfadangaben oder sonstige lange Strings speichern will, viel zu klein bemessen.

128 sollte es IMHO _mindestens_ sein. Im Zweifelsfalle mehr.
Von Michael Weiner am 11.11.2003 um 16:40
Hab vorher falschen Code gepostet:

Hier der richtige:

Private Declare Function WritePrivateProfileString Lib _
"kernel32" Alias "WritePrivateProfileStringA" _
(ByVal lpApplicationName As String, ByVal _
lpKeyName As String, ByVal lpString As String, ByVal _
lpFileName As String) As Integer
Von Michael Weiner am 11.11.2003 um 16:30
Bei VB.NET ist statt Long der Datentyp Integer bei den API-Aufrufen zu verwenden.

Bsp:


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 Long
Von Sebastian Aspermaier am 09.08.2003 um 16:09
@Matthias Lohr:

Ich habe da eien ActiveX-DLL zu geschrieben "INITools"
Sie wird einfach über die Verweise eingebunden und funktioniert dann so:

Man erstellt einen neuen Objektverweis auf die CReader Klasse. Diese beinhaltet 2 Funktionen zum Lesen und Schreiben.
Zum Lesen einfach die Funktion ReadIniFile mit dem vollständigen Pfad und Dateinamen der gewünschten Ini angeben. Die Funktion liefert eine Auflistung mit allen Tags ([]). On ein Tag ([]) subtags (=) enthält kan man mit IsObject feststellen.

Das Handling ist durch die Auflistung denkbat einfach und reduziert den Code wesentlich. Interesse?

Meld dich mal per Email und dem Betreff INITools, dann weis ich worum es geht.


Sebastian
Von Holi am 25.06.2003 um 16:33
Achtung die Dateien können nicht grösser als 64k werden!
Von Matthias Lohr am 06.06.2003 um 12:40
Ist es nicht möglich, ein eigenes Modul zum lesen zu schreiben? Es gibt doch Merkmale wie = oder [ für die einzelnen Sachen
Von St.Marx am 03.06.2003 um 21:14
Hallo

Ich möchte aus eine ini Datei alle Sektionsbezeichnungen einlesen. Dabei sind die Namen der Sektionen nicht bekannt. Wie komme ich zum erfolg ?
Von Christoph Ungersböck am 01.08.2002 um 07:20
Hier ist ein Fehler in der Prozedur INIGetArray!!
Wenn das Array während der Schleife so erweitert wird, ist am Ende immer ein Element zu viel im Array!!
Sollte so ausschaun:
z = 0
Do While l
Von Lestat am 13.07.2002 um 12:35
Läuft bei mir nicht mit einem Novell-Client!!!
Von Sascha Hierold am 08.04.2002 um 08:30
Wenn ich als Reference in meinem VB 6 Programm die Visual C++ Referencen eingestellt habe funktioniert die hier vorgestellte Methode nicht mehr. Gibt es dafür eine Lösung???
Von Jürgen Bähr am 23.01.2002 um 11:56
Ich würde gerne einen Text in eine Datei schreiben, ohne jedoch die OPEN ClOSE
Anweisung zu verwenden, da diese erst nachdem der Befehl CLOSE gesetzt wird den Text aus dem Buffer auf die Platte schreibt. Stürtzt das Programm ab, bevor die CLOSE Anweisung kommt, so sind die Daten im Buffer verloren. Mit WriteProfileString funktioniert dass direkte Schreiben zwar, jedoch stehen in der Datei noch weitere Daten die eigentlich nur für eine INI Datei relevant sind. Diese kann ich nicht gebrauchen. Kann mir jemand sagen wie ich nur den eigentlichen Text in die Datei bekomme?
Über eine Antwort wäre ich sehr erfreut.
M.F.G.
Jürgen Bähr
Von Uwe am 17.12.2001 um 10:19
Wieso macht ihr das nicht mit normalen Dateihandling? Die Such und LöschFunktionen werden natürlich etwas umfangreicher, dafür brauch man sich aber nich mit kernel32 rumschlagen.
Von tobi am 26.11.2001 um 19:02
Funktioniert das ganze auch unter win xp? Wenn nein was gibt es noch für möglichkeiten außer ner api .ini Dateien auszulesen?
Von M. Grass am 21.10.2001 um 14:52
Danke,
Tip 108 (ini-Dateien erstellen ) ist super, genau was ich gesucht habe.
Euer ganzes Angebot ist Toll !! Werde euch weiter emfpehlen.
Wie wäre es , wenn ihr alle Tipps (oder 1-100,101-200,etc...) zum Download anbietet ?
Von wolfgang petzke am 26.06.2001 um 22:57
die Datei, die mit WritePrivateProfileString beschrieben wird,
wird im Speicher gehalten und erst beim Beenden des Programms auf die Platte geschrieben. Wenn man aber die Datei kopieren möchte, nachdem man einige Einträge gemacht hat, müßte man vorher das auf Platte schreiben erzwingen. Wie kann das gemacht werden?

Erstellt: 15.06.2003
Aktualisierung: 15.06.2003
  Autor: ActiveVB
E-Mail: Tipps@ActiveVB.de



Copyright © 1998-2010 by ActiveVB
Alle Rechte vorbehalten.