VB 5/6-Tipp 0108: INI-Dateien Werte und Felder, erstellen und lesen
von ActiveVB
Beschreibung
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: | Verwendete API-Aufrufe: GetPrivateProfileSectionA (GetPrivateProfileSection), GetPrivateProfileStringA (GetPrivateProfileString), WritePrivateProfileSectionA (WritePrivateProfileSection), WritePrivateProfileStringA (WritePrivateProfileString) | Download: |
'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 --------------
Tipp-Kompatibilität:
Windows/VB-Version | Win32s | Win95 | Win98 | WinME | WinNT4 | Win2000 | WinXP |
VB4 | ![]() | ![]() | ![]() | ![]() | ![]() | ![]() | ![]() |
VB5 | ![]() | ![]() | ![]() | ![]() | ![]() | ![]() | ![]() |
VB6 | ![]() | ![]() | ![]() | ![]() | ![]() | ![]() | ![]() |
Ihre Meinung
Falls Sie Fragen zu diesem Artikel haben oder Ihre Erfahrung mit anderen Nutzern austauschen möchten, dann teilen Sie uns diese bitte in einem der unten vorhandenen Themen oder über einen neuen Beitrag mit. Hierzu können sie einfach einen Beitrag in einem zum Thema passenden Forum anlegen, welcher automatisch mit dieser Seite verknüpft wird.
Archivierte Nutzerkommentare
Klicken Sie diesen Text an, wenn Sie die 21 archivierten Kommentare ansehen möchten.
Diese stammen noch von der Zeit, als es noch keine direkte Forenunterstützung für Fragen und Kommentare zu einzelnen Artikeln gab.
Aus Gründen der Vollständigkeit können Sie sich die ausgeblendeten Kommentare zu diesem Artikel aber gerne weiterhin ansehen.
Kommentar 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
Kommentar 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?
Kommentar 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?
Kommentar 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
Kommentar 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
Kommentar 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.
Kommentar 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.
Kommentar 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
Kommentar 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
Kommentar 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
Kommentar von Holi am 25.06.2003 um 16:33
Achtung die Dateien können nicht grösser als 64k werden!
Kommentar 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
Kommentar 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 ?
Kommentar 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
Kommentar von Lestat am 13.07.2002 um 12:35
Läuft bei mir nicht mit einem Novell-Client!!!
Kommentar 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???
Kommentar 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
Kommentar 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.
Kommentar 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?
Kommentar 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 ?
Kommentar 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?