Hallo zusammen,
ich möchte einen Teil eines Textes aus eine Tabelle auslesen und komme nicht weiter.
Hier mein Beispiel:
<Value Name=""Version"">v1.0</Value>"
<Value Name=""VersionType"">String</Value>"
<Value Name=""VersionStr"">F1</Value>"
<Value Name=""InstallMechanism"">IMM</Value>"
<Value Name=""InstallMediaName"">PPKS1890</Value>"
<Value Name=""RetainOnUpgrade"">False</Value>"
<Value Name=""AssociatedData""></Value>"
<Value Name=""AssociatedData""></Value>"
<Value Name=""DisplayNameOverride""></Value>"
<Value Name=""Classification""></Value>"
<Value Name=""Version""></Value>"
<Value Name=""VersionType"">NA</Value>"
<Value Name=""InstallMechanism"">IMM</Value>"
<Value Name=""InstallMediaName"">OPPKS15559000</Value>"
<Value Name=""RetainOnUpgrade"">False</Value>"
<Value Name=""AssociatedData""></Value>"
Der Text hinter "InstallMediaName" und </Value> also "PPKS1890" und "OPPKS15559000" soll entweder herausgefiltert oder mit eine Abfrage abgefragt werden.
Könnt Ihr mir da helfen?
Vielen Dank.
Hallo,
google mal nach "textdatei parsen access vba". Dann gibts zig Beispiele....
Beste Grüße
Andreas
Danke Andyfau,
aber komme so leider nicht weiter. Habe jetzt einige Seiten durchgesucht finde aber nichts brauchbares für meinen Fall. Vielleicht kannst du bzw. jemand anders noch einen Tipp geben.
Gruß
Hallo,
ist der oben gezeigte Text in einem Feld oder sind das mehrere Felder.
Bitte mal genauer erklären.
Hallo,
das ist ein Feld, also alles untereinander und ca. 1800 Einträge.
Zitat von: Tante am September 21, 2022, 17:19:27Vielleicht kannst du bzw. jemand anders noch einen Tipp geben.
Die InStr-Funktion (https://learn.microsoft.com/en-us/office/vba/language/reference/user-interface-help/instr-function) sollte dir beim Kern der Problemstellung weiterhelfen.
Danke,
aber mein SearchString ist doch jedes mal anders weil es viele unterschiedliche Einträge gibt.
Wie kann ich den Wert x zwischen <Value Name=""InstallMediaName""> und </Value>" herausfiltern.
Wenn ich den Befehl richtig verstanden habe geht das nicht damit.
Dim SearchString, SearchChar, MyPos
SearchString ="XXpXXpXXPXXP" ' String to search in.
SearchChar = "P" ' Search for "P".
Sorry, stehe da voll auf dem Schlauch.
Zitat von: Tante am September 21, 2022, 18:32:45Wie kann ich den Wert x zwischen <Value Name=""InstallMediaName""> und </Value>" herausfiltern.
Indem du InStr benutzt, um zuerst die Position von
<Value Name=""InstallMediaName""> zu ermitteln, dann um die Position um das folgende
</Value> zu finden (
Start-Argument für InStr verwenden) .
Mit der Mid-Funktion kannst du dann den Text zwischen der Start- und der Endposition auslesen.
Const HAYSTACK As String = "<Value Name=""Version"">v1.0</Value> und so weiter ....
Const STARTPATTERN As String = "<Value Name=""InstallMediaName"">"
Const ENDPATTERN As String = "</Value>"
Dim startPos As Long
Dim endPos As Long
Do
startPos = InStr(startPos + 1, HAYSTACK, STARTPATTERN) + Len(STARTPATTERN)
If startPos > Len(STARTPATTERN) Then
endPos = InStr(startPos, HAYSTACK, ENDPATTERN)
Debug.Print Mid(HAYSTACK, startPos, (endPos - startPos))
End If
Loop Until startPos = Len(STARTPATTERN)
Wenn Philipp schon den Begriff Pattern ins Spiel bringt, könnte man auch mit RegEx lösen.
Da aber mehr als ein Treffer ausgegeben werden soll, kommt man mit einer einfachen Funktion nicht hin. Ehe man sich also mit einem konkreten Code beschäftigen würde, sollte man wissen,
- woher genau und auf welchem Wege die Verarbeitung laufen soll und
- wohin genau die Rückgabewerte eingebunden werden sollen.
Danke Philipp. Ich habe das allerdings nicht hinbekommen. Ich kenne mich jetzt auch nicht super aus mit VBA. Habe den Code in VBA eingefügt und hatte das dann als Modul. Wenn ich es ausführe passiert nichts. Ich bin mir nicht sicher ob ich irgendetwas nicht beachte.
Zitat von: PhilS am September 21, 2022, 19:27:44 Const HAYSTACK As String = "<Value Name=""Version"">v1.0</Value> und so weiter ....
Const STARTPATTERN As String = "<Value Name=""InstallMediaName"">"
Const ENDPATTERN As String = "</Value>"
Dim startPos As Long
Dim endPos As Long
Do
startPos = InStr(startPos + 1, HAYSTACK, STARTPATTERN) + Len(STARTPATTERN)
If startPos > Len(STARTPATTERN) Then
endPos = InStr(startPos, HAYSTACK, ENDPATTERN)
Debug.Print Mid(HAYSTACK, startPos, (endPos - startPos))
End If
Loop Until startPos = Len(STARTPATTERN)
Danke. Die Daten kommen aus einer Excel Tabelle mit einer Spalte und 1800 Zeilen.
Nach dem Import in Access habe ich ein Feld mit 1800 Zeilen. Jede Value Name ist eine einzelne Zeile.
<Value Name=""InstallMechanism"">IMM</Value>"
<Value Name=""InstallMediaName"">PPKS1890</Value>"
Idealerweise sollte die Rückgabe in eine Tabelle ausgegeben werden, die dann diese Werte z.B.(PPKS1890) mit einer anderen Tabelle über einen Abfrage vergleicht, ob diese Werte dort vorhanden sind.
Hoffe ich konnte es einigermaßen verständlich beschreiben.
Zitat von: ebs17 am September 22, 2022, 09:52:27Wenn Philipp schon den Begriff Pattern ins Spiel bringt, könnte man auch mit RegEx lösen.
Da aber mehr als ein Treffer ausgegeben werden soll, kommt man mit einer einfachen Funktion nicht hin. Ehe man sich also mit einem konkreten Code beschäftigen würde, sollte man wissen,
- woher genau und auf welchem Wege die Verarbeitung laufen soll und
- wohin genau die Rückgabewerte eingebunden werden sollen.
Zitat von: ebs17 am September 22, 2022, 09:52:27Wenn Philipp schon den Begriff Pattern ins Spiel bringt, könnte man auch mit RegEx lösen.
Da aber mehr als ein Treffer ausgegeben werden soll, kommt man mit einer einfachen Funktion nicht hin. Ehe man sich also mit einem konkreten Code beschäftigen würde, sollte man wissen,
- woher genau und auf welchem Wege die Verarbeitung laufen soll und
- wohin genau die Rückgabewerte eingebunden werden sollen.
Zitat von: ebs17 am September 22, 2022, 09:52:27Wenn Philipp schon den Begriff Pattern ins Spiel bringt, könnte man auch mit RegEx lösen.
Da aber mehr als ein Treffer ausgegeben werden soll, kommt man mit einer einfachen Funktion nicht hin. Ehe man sich also mit einem konkreten Code beschäftigen würde, sollte man wissen,
- woher genau und auf welchem Wege die Verarbeitung laufen soll und
- wohin genau die Rückgabewerte eingebunden werden sollen.
Zitat von: Tante am September 22, 2022, 10:03:35Wenn ich es ausführe passiert nichts. Ich bin mir nicht sicher ob ich irgendetwas nicht beachte.
Der Code gibt die gesuchten Werte im Direktfenster der VBA-Umgebung aus. - Wenn du das nicht eingeblendet hast, siehst du nix.
Um das Direktfenster einzublenden, entweder Menü "Ansicht" - "Direktfenster" oder [STRG]+[G] auf der Tastatur verwenden.
ZitatJede Value Name ist eine einzelne Zeile
Zeile gleich Datensatz?
Dann würde man also nicht einen 1.800-Zeilen-Text auswerten, sondern die Zeilen auf das benötigte filtern.
WHERE Instr(1, FeldY, "InstallMediaName") > 0
Damit braucht man sich nur noch mit den interessierenden zwei Datensätzen beschäftigen.
Als Abfrage etwa (ungetestet)
SELECT
FeldY,
RegExReplace(FeldY, "^.*>([A-Z0-9]+)<.*$", "$1") AS Content
FROM
TabelleX
WHERE
Instr(1, FeldY, "InstallMediaName") > 0
RegExReplace aus Codebeispiel - "Intelligente" Textanalyse (https://www.ms-office-forum.net/forum/showpost.php?p=1474906&postcount=9), ersten Codeblock in ein Standardmodul übernehmen
Code_Fehler.JPG
Ich bekomme diese Fehlermeldung- Meine Tabelle heißt Tabelle1 und mein Feld heißt Feld1.
Um das Direktfenster einzublenden, entweder Menü "Ansicht" - "Direktfenster" oder [STRG]+[G] auf der Tastatur verwenden.
[/quote]
Hmm....auch das Funktioniert leider nicht.
Zitat von: Tante am September 23, 2022, 10:23:10Hmm....auch das Funktioniert leider nicht.
Bitte gewöhnt dir an statt "funktioniert nicht" zu schreiben was genau passiert oder nicht passiert.
Das Direktfenster einzublenden funktioniert garantiert wie beschrieben. Im worst case ist das Fenster ganz an den unteren Rand gezogen, so dass man es kaum sehen kann.
Entschuldigung, da hast natürlich absolut recht. Funktioniert nicht ist nichts aussagend.
Ich konnte das Direktfenster einblenden jedoch befanden sich darin keinerlei Einträge.
Hallo zusammen,
könnte mich jemand hier noch unterstützen, ich komme leider nicht weiter.
Vielen Dank.
Du hast anscheinend einen Teil meines Vorschlages probiert. Aber Du hast die vorangestellte Schlussfolgerung nicht bewertet, und Du hast nicht den Satz nach dem Codeblock sichtbar wahrgenommen.
Infolgedessen kann ich nur der Meinung sein, dass Du noch nicht vollständig gelesen hast und also noch einige Zeit für dieses brauchst. Diese Zeit bekommst Du.
Zitat von: Tante am September 23, 2022, 11:50:42Ich konnte das Direktfenster einblenden jedoch befanden sich darin keinerlei Einträge.
Schwer zu sagen, was dafür die Ursache ist.
Du hast den Code in ein Prozedur in einem allgemeinen Modul kopiert?,
Du hast die in meinem Beispiel verkürzte HAYSTACK-Konstante mit dem vollständigen Text initialisiert?
Du hast den Code auch wirklich ausgeführt?
@ebs17, ich glaube dein Lösungsvorschlag ist hier nicht direkt anwendbar, weil eben nicht Zeilen=Datensätze, sondern Zeilen="Textzeilen innerhalb eines Datensatzes" sind.
Zitathier nicht direkt anwendbar
Da magst Du recht haben, die Beschreibung ist für mich aber nicht klar, sondern interpretierbar.
Bei einem Text über alles würde ein Code etwas anders aussehen, schon mal wegen mindestens zwei Rückgabewerten, die ich dann auch in eigenen Datensätzen ablegen würde. Damit wird auch gleich klar, dass man sich mit dem DANACH und was sonst noch intensiver beschäftigen müsste, um im Nachgang eine direkte Nutzbarkeit zu haben. Ohne das Wissen darum sind Codes für die Tonne, es sei denn, Dritte nehmen diese für ein vertieftes Lernen.
Man darf aber auch die Frage stellen: Warum zerlegt man die Textzeilen nicht gleich bei Import in Datensätze, als Minimum einer Aufbereitung, wo doch sichtbar maximale Schwierigkeiten bestehen, mit dem Gesamtblock überhaupt umzugehen. Einer weiteren und laufenden Auswertung ist das, selbst wenn man es beherrscht, ebenfalls nicht förderlich (Performance, Komplexität, Fehleranfälligkeit).
Womöglich bis sicher werden noch weitere Informationen atomar benötigt.
Da könnte ich provokativ nachfragen, wieviele Instr-Funktionen mit Do ... Loop man nachreichen möchte.
@Tante Versuche es doch noch einmal mit Eberhards Abfrage.
Die Fehlermeldung, die du beim ersten Mal bekommen hast, stammt
von dem fehlenden Verweis auf die entsprechende Bibliothek, -
Microsoft VBScript Regular Expressions 5.5 (oder höher).
Gehe also im VBE auf das Menu "Verweise" und setze ein Häkchen
bei der o.a. DLL.
gruss ekkehard
@Eberhard
ZitatWarum zerlegt man die Textzeilen nicht gleich bei Import in Datensätze
Dies
ZitatNach dem Import in Access habe ich ein Feld mit 1800 Zeilen. Jede Value Name ist eine einzelne Zeile.
deutet aber darauf hin, dass es so ist. Ich interpretiere hier Zeile = DS, was ja auch deiner
Abfrage zu Grunde liegt. Deshalb mein Hinweis darauf.
gruss ekkehard
@ekkehard:
Nein, kein Verweisproblem. Die verwendete Funktion verwendet Late Binding. Allerdings müsste man sie für eine Verwendung in seine DB übernehmen (inkl. der Property => eine Instanz für alles).
@Eberhard
O.K., das hatte ich übersehen, will sagen, dass ich mir deinen Link nicht
angeschaut hatte.
Das hat der TS aber auch nicht, und wenn hat er es nicht verstanden.
Ich umgehe jetzt mal deine Domäne "lesen und verstehen" und helfe ihm aus
der Patsche.
@Tante Du musst von dem Code aus Eberhards Link die Member-Variable
Private pRegEx As Object
und die beiden Functions
Public Property Get oRegEx() As Object
If (pRegEx Is Nothing) Then Set pRegEx = CreateObject("Vbscript.Regexp")
Set oRegEx = pRegEx
End Property
sowie
Public Function RegExReplace(ByVal SourceText As String, _
ByVal SearchPattern As String, _
ByVal ReplaceText As String, _
Optional ByVal bIgnoreCase As Boolean = True, _
Optional ByVal bGlobal As Boolean = True, _
Optional ByVal bMultiLine As Boolean = True) As String
With oRegEx
.Pattern = SearchPattern
.IgnoreCase = bIgnoreCase
.Global = bGlobal
.Multiline = bMultiLine
RegExReplace = .Replace(SourceText, ReplaceText)
End With
End Function
in ein allgemeines Modul deiner DB kopieren, dann sollte es mit Eberhards
Abfrage auch ohne Fehlermeldung klappen.
gruss ekkehard
Hallo zusammen,
es hat zum Teil funktioniert :) . Wenn ich die Abfrage ausführe erhalte ich folgendes Ergebnis:
Feld1 Content
<Value Name="InstallMediaName"></Value> <Value Name="InstallMediaName"></Value>
<Value Name="InstallMediaName"></Value> <Value Name="InstallMediaName"></Value>
<Value Name="InstallMediaName">PPKS1890</Value> <Value Name="InstallMediaName">PPKS1890</Value>
<Value Name="InstallMediaName">OPPKS15559000f</Value> <Value Name="InstallMediaName">OPPKS15559000</Value>
Alle anderen Zeilen außer InstallMediaName wurden herausgefiltert. Es wurde ein zweites Feld (Content) hinzugefügt. Das ist auch Prima. Jedoch sollte in diesem Feld nur der Inhalt aus diese Zeile ausgelesen werden. Also zum Beispiel sollte im Feld Content nur PPKS1890 oder OPPKS15559000f stehen.
Ich habe keine Vorstellung davon, WAS genau WOMIT genau Du etwas anstellst. Fragen beantwortest Du auch nicht wirklich, und verdammt, mein Zauberstab ist unter den Schrank gerollt.
Wenn das Beschreiben nicht so Dein Ding ist, gäbe es einen Ausweg. Lade hier eine Demo hoch, so dass man sich an vorhandenen Fakten orientieren könnte. Da könnte man auch dem "ungetestet" den Inhalt nehmen.
Hallo Tante,
Bei RegEx kann ich dir (Asche auf mein Haupt) leider nicht weiterhelfen.
Da Philips Function aber funktioniert, kannst du auch diese in der
Abfrage verwenden
angepasste Function
Public Function GetInstalledMediaName(sFeldInhalt As String) As String
Const STARTPATTERN As String = "<Value Name=""InstallMediaName"">"
Const ENDPATTERN As String = "</Value>"
Dim startPos As Long
Dim endPos As Long
Do
startPos = InStr(startPos + 1, sFeldInhalt, STARTPATTERN) + Len(STARTPATTERN)
If startPos > Len(STARTPATTERN) Then
endPos = InStr(startPos, sFeldInhalt, ENDPATTERN)
'zum Anschauen im Direktfenster
Debug.Print Mid(sFeldInhalt, startPos, (endPos - startPos))
'zur Rückgabe an die Abfrage
GetInstalledMediaName = Mid(sFeldInhalt, startPos, (endPos - startPos))
End If
Loop Until startPos = Len(STARTPATTERN)
End Function
Abfrage
SELECT
FeldY,
GetInstalledMediaName(FeldY) AS Content
FROM
TabelleX
WHERE
Instr(1, FeldY, "InstallMediaName") > 0
Wahrscheinlich nicht der Performance-Burner, aber bei nur ca. 180 DS aus
der Gesamtmenge fällt das wohl nicht so ins Gewicht.
gruss ekkehard
Zitat von: ebs17 am September 27, 2022, 13:10:10Ich habe keine Vorstellung davon, WAS genau WOMIT genau Du etwas anstellst. Fragen beantwortest Du auch nicht wirklich, und verdammt, mein Zauberstab ist unter den Schrank gerollt.
Wenn das Beschreiben nicht so Dein Ding ist, gäbe es einen Ausweg. Lade hier eine Demo hoch, so dass man sich an vorhandenen Fakten orientieren könnte. Da könnte man auch dem "ungetestet" den Inhalt nehmen.
Hallo Eberhard,
zuerst vielen Dank das du dich der Sache freiwillig annimmst und hilfst! Ich erwarte natürlich nicht das du dein Zauberstab unter dem Schrank wieder herholst. Aus meiner Sicht (einem Access Laien) habe ich es umfangreich versucht darzustellen. Vielleicht entspricht es nicht den Vorstellungen eines Gurus wie dir. Bitte habe Nachsicht, dass dem einen oder anderen das Wissen oder Verständnis fehlt was für Info benötigt werden um solch ein Problem zu lösen.
Viele Grüße
Hallo Ekkehard,
super, vielen vielen Dank!! Das funktioniert. Problem ist gelöst!