Importieren von html-code in Zelle klappt, benötige aber nur einen Ausschnitt vom Code
Hallo zusammen,
hiermit importiere ich den html code einer Datei in eine Zelle.
Nun möchte ich den html Code aber nicht komplett importieren sondern nur einen Ausschnitt
<table> bis </table>
Jemand eine Idee?
hiermit importiere ich den html code einer Datei in eine Zelle.
If Trim(UCase(Dir(d & "\" & f))) <> Trim(UCase(f)) Then
MsgBox "htmlquelldatei nicht gefunden - Nächster Artikel"
Sheets("Makro").Activate
Range("A" & 10 + Error_not_found_zaehler).Value = Artikelnummer
GoTo Auslesen
Else
' Handle...
h = FreeFile
' Öffnen...
Open d & "\" & f For Binary Access Read As #h
' Init...
r = String(FileLen(d & "\" & f), " ")
' Lesen...
Get #h, , r
' Schließen...
Close #h
' Aufräumen...
r = Replace(r, vbCrLf, Chr(10))
Workbooks("Beispiel_Eigenschaften_steffen.xlsm").Activate
Sheets("Tabelle1").Activate
Range("AA" & Eigenschaftsgruppenzaehler).Value = r
'Export in .html umbezeichnen
Name Speicherpfad & Artikelnummer & ".txt" As Speicherpfad & Artikelnummer & ".htm"
End If
<table> bis </table>
Jemand eine Idee?
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 183324
Url: https://administrator.de/contentid/183324
Ausgedruckt am: 26.11.2024 um 06:11 Uhr
24 Kommentare
Neuester Kommentar
Moin SteveNow,
unter der Annahme, das in Deinem html nur eine Tabelle existiert?, etwa so:
Die ersten beiden Zeilen sind notwendig, falls im <table>-Tag noch weitere Attribute notiert sind (und weil RegEx in Excel-VBA nicht mit einer Zeile zu erledigen ist):
PS: Benutze bitte die -Tags beim Posten von Quelltext - auch nachträglich.
Freundliche Grüße von der Insel - Mario
unter der Annahme, das in Deinem html nur eine Tabelle existiert?, etwa so:
...
r = Mid(r, InStr(1, r, "<table", vbTextCompare) + 6) ' alles nach <table
r = Mid(r, InStr(1, r, ">", vbTextCompare) + 1) ' alles nach >
r = Mid(r, 1, InStr(1, r, "</table>", vbTextCompare) - 1) ' alles bis </table>
r = Replace(r, vbCrLf, Chr(10)) ' Deine Zeile
...
Die ersten beiden Zeilen sind notwendig, falls im <table>-Tag noch weitere Attribute notiert sind (und weil RegEx in Excel-VBA nicht mit einer Zeile zu erledigen ist):
<table border="1" cellspacing="2">
PS: Benutze bitte die -Tags beim Posten von Quelltext - auch nachträglich.
Freundliche Grüße von der Insel - Mario
Hallo SteveNow!
Anderes Beispiel ohne RegExp:
Gruß Dieter
[edit]
@bastla
[/edit]
Anderes Beispiel ohne RegExp:
Option Compare Text
Const Tag1 = "<table>"
Const Tag2 = "</table>"
Const Text = "IrgendEinText<table>Dein Text</table>NochIrgendEinText"
Sub Test()
Dim Result As String
If InStr(Text, Tag1) > 0 And InStr(Text, Tag2) > 0 Then
Result = Split(Split(Text, Tag1)(1), Tag2)(0) 'Ergebnis in Result = "Dein Text"
Else
Result = "Nothing"
End If
MsgBox Result
End Sub
Gruß Dieter
[edit]
@bastla
'ich borge auch mal kurz bei Dieter
Klauen, triffts wohl eher...[/edit]
@mario
Grüße
bastla
[Edit] @Dieter
[/Edit]
und weil RegEx in Excel-VBA nicht mit einer Zeile zu erledigen ist
Naja, mehr als eine Zeile war's bei Dir ja auch ...r = "IrgendEinText<table border=""1"" cellspacing=""2"">Dein Text</table>NochIrgendEinText" 'ich borge auch mal kurz bei Dieter ;-)
Set rE = CreateObject("VbScript.RegExp")
rE.Pattern = "<table.*>(.+)</table>"
If rE.Test(r) Then Inhalt = rE.Execute(r)(0).SubMatches(0)
MsgBox Inhalt
bastla
[Edit] @Dieter
Klauen, triffts wohl eher...
Aber nein - kannst Du ja jederzeit wieder zurück haben (und Mario wird Dir, wie ich ihn einschätze, seine Zusätze sicherlich auch noch überlassen) ... [/Edit]
Moin SteveNow,
ich antworte mal anstelle von didi1954, damit Du nicht solange warten musst:
Die Rückgabe von 'DeinText' liegt daran, das in dem Vorschlag lediglich eine mögliche Vorgehensweise beschrieben wird, die aber nicht an oder auf die von Dir bereits geposteten Zeilen angepasst oder bezogen ist. Ein innerhalb der <table>-Tags stehender Mustertext (siehe Zeile 6)
wird entspr. aufbereitet - übrig bleibt: s.o.
Die Lösung berücksichtigt aber nicht eventuelle, im <table>-Tag stehende Attribute (siehe dazu meinen 1. Post).
Freundliche Grüße von der Insel - Mario
ich antworte mal anstelle von didi1954, damit Du nicht solange warten musst:
Die Rückgabe von 'DeinText' liegt daran, das in dem Vorschlag lediglich eine mögliche Vorgehensweise beschrieben wird, die aber nicht an oder auf die von Dir bereits geposteten Zeilen angepasst oder bezogen ist. Ein innerhalb der <table>-Tags stehender Mustertext (siehe Zeile 6)
Const Text = "IrgendEinText<table>Dein Text</table>NochIrgendEinText"
Die Lösung berücksichtigt aber nicht eventuelle, im <table>-Tag stehende Attribute (siehe dazu meinen 1. Post).
Freundliche Grüße von der Insel - Mario
Hallo SteveNow!
Naja, die Codezeile mit dem Splits gibt das zurück, was zwischen den Table-Tags steht, wobei das aber nur funktioniert, wenn die Tags immer gleich sind d.h. der Tag1 (<table...>) muß in allen Html-Dateien identisch sein. Insofern, ist bastlas Lösung mit RegExp die bessere und sichere Variante.
Bleibt aber noch die Frage offen, ob die Html-Datei immer nur 1 Table enthält?
Wäre auch nicht schlecht, wenn Du den kompletten Code-Abschnitt von Sub-Begin bis Sub-Ende posten würdest, denn da ließe sich einiges wesentlich verbessern
Gruß Dieter
[edit] Mario war etwas schneller und hat's auch schön erklärt [/edit]
@bastla
Naja, die Codezeile mit dem Splits gibt das zurück, was zwischen den Table-Tags steht, wobei das aber nur funktioniert, wenn die Tags immer gleich sind d.h. der Tag1 (<table...>) muß in allen Html-Dateien identisch sein. Insofern, ist bastlas Lösung mit RegExp die bessere und sichere Variante.
Bleibt aber noch die Frage offen, ob die Html-Datei immer nur 1 Table enthält?
Wäre auch nicht schlecht, wenn Du den kompletten Code-Abschnitt von Sub-Begin bis Sub-Ende posten würdest, denn da ließe sich einiges wesentlich verbessern
Gruß Dieter
[edit] Mario war etwas schneller und hat's auch schön erklärt [/edit]
@bastla
Aber nein - kannst Du ja jederzeit wieder zurück haben (und Mario wird Dir, wie ich ihn einschätze, seine Zusätze sicherlich auch noch überlassen) ...
Nö danke, der ist jetzt abgenutzt und Du darfst ihn gerne behalten...
Moin SteveNow,
es wäre einfacher für uns alle, wenn Du alle Posts beachten könntest. In meinem ersten Post habe ich eine fertige Lösung angeboten, inklusive der Stelle, wo es eingefügt werden muss.
Leider bist Du bis jetzt nicht darauf eingegangen. Ebensowenig hast Du die Zeile gepostet, die nach Deiner Aussage einen Fehler auswirft. Sei es darum, hier nochmals ein Versuch zur Hilfe:
- aus dem soeben von Dir geposteten Quelltext entfernst Du Zeile 302 bis Zeile 316 ersatzlos.
- von dem von mir oben nochmals geposteten Quelltext kopierst Du die ersten 3 Zeilen vor Deine Zeile 331.
Das funktioniert dann mit der oben gemachten Einschränkung, die Frage dazu ('mehr als eine Tabelle?') hast Du ebenfalls noch nicht beantwotet.
Verbesserungspotential gibt es im Quelltext genug, aber das kann man angehen, wenn es Dir wichtig erscheint und Grundfunktionalität gegeben ist.
Freundliche Grüße von der Insel - Mario
es wäre einfacher für uns alle, wenn Du alle Posts beachten könntest. In meinem ersten Post habe ich eine fertige Lösung angeboten, inklusive der Stelle, wo es eingefügt werden muss.
r = Mid(r, InStr(1, r, "<table", vbTextCompare) + 6) ' alles nach <table
r = Mid(r, InStr(1, r, ">", vbTextCompare) + 1) ' alles nach >
r = Mid(r, 1, InStr(1, r, "</table>", vbTextCompare) - 1) ' alles bis </table>
r = Replace(r, vbCrLf, Chr(10)) ' Deine Zeile
Leider bist Du bis jetzt nicht darauf eingegangen. Ebensowenig hast Du die Zeile gepostet, die nach Deiner Aussage einen Fehler auswirft. Sei es darum, hier nochmals ein Versuch zur Hilfe:
- aus dem soeben von Dir geposteten Quelltext entfernst Du Zeile 302 bis Zeile 316 ersatzlos.
- von dem von mir oben nochmals geposteten Quelltext kopierst Du die ersten 3 Zeilen vor Deine Zeile 331.
Das funktioniert dann mit der oben gemachten Einschränkung, die Frage dazu ('mehr als eine Tabelle?') hast Du ebenfalls noch nicht beantwotet.
Verbesserungspotential gibt es im Quelltext genug, aber das kann man angehen, wenn es Dir wichtig erscheint und Grundfunktionalität gegeben ist.
Freundliche Grüße von der Insel - Mario
Hallo SteveNow!
BTW: Mein Ansatz war nix für Dich?
Grüße
bastla
Was ist mit Zeile 4 gemeint? r = Replace(r, vbCrLf, Chr(10))
Die Zeile stand doch so schon bei Dir - damit werden "Windows"-Zeilenschaltungen zu Zeilen-Umbrüchen innerhalb einer Excel-Zelle gemacht.damit wird der html quelltext eingefügt, das ist klar
ist allerdings eine nicht haltbare Behauptung ...BTW: Mein Ansatz war nix für Dich?
Grüße
bastla
Hallo SteveNow!
Wenn ich Dein Skript einigermaßen richtig verstanden habe, dann könnte es hiermit funktionieren:
Gruß Dieter
[edit] Codezeile 80/81 geändert. Jetzt komplett mit <table und </table> [/edit]
Wenn ich Dein Skript einigermaßen richtig verstanden habe, dann könnte es hiermit funktionieren:
Option Explicit
Option Compare Text
'Externe Pause-Funktion in Millsekunden
Public Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
Private Const EigenschaftenStart = 2
Private Const ErrMsg1 = "Abbruch! Vorlage nicht gefunden:" & vbCr & vbCr
Private Const ErrMsg2 = "Abbruch! ArtikelNr in Tabelle 1 Zeile %1 fehlt!"
Private Const ErrMsg3 = "Datei nicht gefunden:" & vbCr & vbCr
Sub Kopieren()
Dim Fso As Object, Wks1 As Worksheet, Wks2 As Worksheet, WksV As Worksheet
Dim Found As Range, Eigenschaft As Variant, Eigenschaftswert As Variant
Dim Speicherpfad As String, Path As String, ArtikelNr As String, HtmText As String
Dim TableText As String, c As Integer, i As Long, ErrCounter As Long
Set Fso = CreateObject("Scripting.FileSystemObject") 'Klasse mit Dateifunktionen einbinden
Speicherpfad = Sheets("Makro").Range("A2").Value 'Speicherpfad festlegen
If Right(Speicherpfad, 1) <> "\" Then Speicherpfad = Speicherpfad & "\"
Path = Speicherpfad & "Vorlage.xlsx"
If Fso.FileExists(Path) = False Then 'Test ob Vorlage-Datei existiert, ansonsten Abbrechen
MsgBox ErrMsg1 & Path, vbExclamation, "Fehler...": Exit Sub
End If
With Workbooks.Open(Path) 'Vorlage-Sheet importieren (wird am Ende wieder entfernt)
.Sheets("Vorlage").Copy After:=ThisWorkbook.Sheets("Tabelle2")
.Close False
End With
Set Wks1 = Sheets("Tabelle1") 'Tabelle 1 zuweisen
Set Wks2 = Sheets("Tabelle2") 'Tabelle 2 zuweisen
Set WksV = Sheets("Vorlage") 'Tabelle Vorlage zuweisen
'Schleife bis zur letzten Zeile mit Inhalt in Tabelle 1 Spalte H
For i = EigenschaftenStart To Wks1.Cells(Wks1.Rows.Count, "H").End(xlUp).Row
ArtikelNr = Wks1.Cells(i, "C")
If ArtikelNr = "" Then 'Test ob ArtikelNr eingetragen ist, ansonsten abbrechen
MsgBox Replace(ErrMsg2, "%1", i), vbExclamation, "Fehler...": GoTo CleanUp
End If
'Eigenschaftsgruppe in Tabelle 2 suchen
Set Found = Wks2.Columns("A").Find(Wks1.Cells(i, "H"), LookIn:=xlValues, LookAt:=xlWhole)
'Test ob Eigenschaftsgruppe in Tabelle 2 vorhanden, ansonsten ArtikelNr in Sheet Makro eintragen (A10+)
If Found Is Nothing Then
Sheets("Makro").Range("A10").Offset(ErrCounter, 0) = ArtikelNr
ErrCounter = ErrCounter + 1
Else
Eigenschaft = Wks2.Cells(Found.Row, "C").Resize(1, 15).Value 'Werte laden: Tabelle 2 Spalte C:Q
Eigenschaftswert = Wks1.Cells(i, "I").Resize(1, 15).Value 'Werte laden: Tabelle 1 Spalte I:W
For c = 1 To UBound(Eigenschaft, 2) 'Werte in Sheet Vorlage eintragen
With WksV
.Cells(c, "A") = Eigenschaft(1, c)
.Cells(c, "B") = Eigenschaftswert(1, c)
End With
Next
Path = Speicherpfad & ArtikelNr & ".htm" 'Htm-Pfad festlegen
'Vorlage als ArtikelNr-Htm speichern
ThisWorkbook.PublishObjects.Add(xlSourceRange, Path, "Vorlage", "$A$1:$B$15", xlHtmlStatic).Publish
'Sleep 500 'falls nötig, Kommentar am Zeilenanfang entfernen
If Fso.FileExists(Path) Then 'Test ob Htm-Datei gespeichert wurde
With Fso.OpenTextFile(Path)
HtmText = .ReadAll 'Htm-Datei einlesen
.Close
End With
'Table-Inhalt entsprechend filtern
TableText = "<table" & Split(Split(HtmText, "<table", 2)(1), "</table>", 2)(0) & "</table>"
Wks1.Cells(i, "AA") = TableText 'Table-Text in Tabelle 1 eintragen
Else
MsgBox ErrMsg3 & Path, vbExclamation, "Fehler..."
End If
End If
Next
CleanUp:
With Application
.DisplayAlerts = False
WksV.Delete
.DisplayAlerts = True
End With
End Sub
Gruß Dieter
[edit] Codezeile 80/81 geändert. Jetzt komplett mit <table und </table> [/edit]
Hallo Hallo SteveNow!
Bei Makroaufzeichnungen, werden alle Aktivitäten aufgezeichnet d.h. Zellen aktivieren(.Activate)/selektieren (.Select). In VBA-Code ist das unnötig, weil Du die Zellen ja auf verschiedene Arten direkt ansprechen kannst z.B.:
Wenn ein Sheet Aktiv ist:
Wenn ein Sheet nicht Aktiv ist:
oder
oder
und wenn auf 2 oder mehr Sheets zugegriffen wird, dann werden die Sheets-Objecte einer Variablen zugewiesen z.B:
oder
Und nicht vergessen, den Thread mit einem grünen Häkchen zu versehen
Gruß Dieter
Danke, funktioniert einwandfrei !
Freu mich zu hören @Dieter: Deins muss ich noch probieren - recht komplex das ganze ;)
Das scheint nur so, weil die vielen Activate fehlenBei Makroaufzeichnungen, werden alle Aktivitäten aufgezeichnet d.h. Zellen aktivieren(.Activate)/selektieren (.Select). In VBA-Code ist das unnötig, weil Du die Zellen ja auf verschiedene Arten direkt ansprechen kannst z.B.:
Wenn ein Sheet Aktiv ist:
Range("A1").Value = Wert
Cells(1,1).Value = Wert 'Cells(Zeilennumer, Spaltennummer)
....
Sheets("Name").Activate
Range("A1").Value = Wert
Cells(1,1).Value = Wert
....
Sheets("Name").Range("A1").Value = Wert
Sheets("Name").Cells(1,1).Value = Wert
....
With Sheets("Name")
.Range("A1").Value = Wert
.Cells(1,1).Value = Wert
....
End With
Dim Wks1 As Worksheet, Wks2 As Worksheet
Set Wks1 = Sheets("Name1")
Set Wks2 = Sheets("Name2")
Wks1.Range("A1") = Wert1
Wks2.Range("A1") = Wert2
...
Dim Wks1 As Worksheet, Wks2 As Worksheet
Set Wks1 = Sheets("Name1")
Set Wks2 = Sheets("Name2")
With Wks1
.Range("A1") = Wert1
.Range("A2") = Wert2
End With
With Wks2
.Range("A1") = Wert2
.Range("A2") = Wert2
End With
...
Und nicht vergessen, den Thread mit einem grünen Häkchen zu versehen
Gruß Dieter
Hallo SteveNow!
Gruß Dieter
ich hab jetzt in dem hübschen Makro vom DIeter etwas "rumgepfuscht" ..
Bisher läuft alles ganz gut..
Das ist so OKBisher läuft alles ganz gut..
Gruß Dieter