[VB] HTML file (table's) naar Excel wegschrijven

Pagina: 1
Acties:

  • kippy
  • Registratie: September 2004
  • Laatst online: 09:31
ik ben bezig met een programma om een helle hoop gegevens uit een html te halen en in een Excel sheet weg te schrijven.

Dit is mij ook gelukt, maar ik denk dat ik dit heel omslagtig doe.

code:
1
2
3
4
5
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"><HTML><!-- Constructed with LabVIEW Report Generation --><HEAD><TITLE></TITLE></HEAD><BODY><BR>8/31/20043:56 PM<BR><TABLE WIDTH="400.000000"><TR><TD>Typenumber:</TD><TD>tl280n42</TD></TR><TR><TD></TD><TD></TD></TR><TR><TD>Voltage:</TD><TD>229.66</TD></TR><TR><TD>Current:</TD><TD>0.777</TD></TR><TR><TD>Power:</TD><TD>178.21</TD></TR><TR><TD>Powerfactor:</TD><TD>0.998</TD></TR><TR><TD>Frequency:</TD><TD>50.00</TD></TR><TR><TD>THD :</TD><TD>3.942</TD></TR></TABLE><BR><TABLE WIDTH="400.000000"><TR><TD>    1 Harm.</TD><TD></TD>
<TD>778.030</TD><TD>  mA</TD><TD></TD><TD>100.000</TD><TD>  %</TD></TR><TR><TD>    2 Harm.</TD><TD></TD><TD>  0.622</TD><TD>  mA</TD><TD></TD>
<TD>  0.080</TD><TD>  %</TD></TR><TR><TD>    3 Harm.</TD><TD></TD><TD> 18.144</TD>
<TD>  mA</TD><TD></TD><TD>  2.332</TD><TD>  %</TD></TR><TR><TD>    4 Harm.</TD><TD></TD><TD>  0.187</TD><TD>  mA</TD><TD></TD><TD>  0.024</TD><TD>  %</TD></TR><TR><TD>    5 Harm.</TD><TD></TD><TD>  3.867</TD><TD>  mA</TD><TD></TD>
</TR></TABLE></BODY></HTML>


code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
                'vvvvvvvv***Array***vvvvvvvv
                    een = Asc(een)
                    Dim intI As Integer, intJ As Integer
                    intJ = 1
                    For intI = 0 To 9
                        For intJ = 0 To 99
                            DynamicArray(intI, intJ) = (Chr(een) & (intJ + twee))
                        Next intJ
                        een = een + 1
                    Next intI
                '^^^^^^^^^Array***^^^^^^^^^

                    intI = 0
                    intJ = -1
                    
                    Dim fs, f, ts, s
                    Set fs = CreateObject("Scripting.FileSystemObject")
                    filetoopen = Application.GetOpenFilename("Harmonic files (*.prn), *.prn")
                    Set f = fs.GetFile(filetoopen)
                    Set ts = f.OpenAsTextStream()
                    Do While s <> "</BODY>"
                    s = ts.read(1)
                        If s = "<" Then
                            s = ts.read(1)
                                If s = "T" Then
                                    s = ts.read(1)
                                        If s = "D" Then
                                            s = ts.read(1)
                                                If s = ">" Then
                                                    s = ts.read(1)
                                                        If s <> "<" Then
                                                            twee = ""
                                                            Do While s <> "<"
                                                                    If s <> "<" Then
                                                                        twee = (twee & s)
                                                                    End If
                                                                s = ts.read(1)
                                                            Loop
                                                            Worksheets("Sheet1").Range(DynamicArray(intI, intJ)) = twee
                                                        intI = intI + 1
                                                        End If
                                                End If
                                        Else
                                            If s = "R" Then
                                                intJ = intJ + 1
                                                intI = 0
                                            End If
                                        End If
                                Else
                                    If s = "/" Then
                                        s = ts.read(1)
                                            If s = "B" Then
                                                s = ts.read(4)
                                                    If s = "ODY>" Then
                                                        s = "</BODY>"
                                                    End If
                                            End If
                                    End If
                                End If
                        End If
                    'MsgBox twee
                    Loop
                    ts.Close


iamdn een idee om dit makkelijker te berijken, ik heb het al geprobeert met
code:
1
ts.readline

maar dan moet ik daarna weer die <TD> en andere zut weg filteren, wat me al helemaal niet lukt.

  • CodeCaster
  • Registratie: Juni 2003
  • Niet online

CodeCaster

Stop AI Slop

Wel...

code:
1
2
s = ts.read(4)
                        If s = "<TD>" Then


?

https://oneerlijkewoz.nl
Op papier is hij aan het tekenen, maar in de praktijk...


  • kippy
  • Registratie: September 2004
  • Laatst online: 09:31
CodeCaster schreef op dinsdag 08 maart 2005 @ 15:45:
Wel...

code:
1
2
s = ts.read(4)
                        If s = "<TD>" Then


?
Dat hoopte ik ook idd, maar dat zal niet werken, omdat je op dat moment elke keer 4 tekens inleest.
je leest dan ook dingen in als
code:
1
D>45

op dat moment dal ik dus waardes missen (absoluut niet de bedoeling)

  • CodeCaster
  • Registratie: Juni 2003
  • Niet online

CodeCaster

Stop AI Slop

Als je een regel inleest:

code:
1
Instr(LCase(Regel),"<td>")


Geeft dan de positie terug van de tekst "<td">. Hoofdlettergevoelig, vandaar de LCase(), die het omvormt naar kleine letters.

Hierna:

code:
1
Regel = Replace(Regel, "<td>", "")


Verwijdert de <td> tag uit de regel, zodat je deze direct in Excel kunt plaatsen.

Replace is ook hoofdlettergevoelig, zijn die HTMLs consequent hierin?

https://oneerlijkewoz.nl
Op papier is hij aan het tekenen, maar in de praktijk...


  • kippy
  • Registratie: September 2004
  • Laatst online: 09:31
CodeCaster schreef op dinsdag 08 maart 2005 @ 15:53:
Als je een regel inleest:

code:
1
Instr(LCase(Regel),"<td>")


Geeft dan de positie terug van de tekst "<td">. Hoofdlettergevoelig, vandaar de LCase(), die het omvormt naar kleine letters.

Hierna:

code:
1
Regel = Replace(Regel, "<td>", "")


Verwijdert de <td> tag uit de regel, zodat je deze direct in Excel kunt plaatsen.

Replace is ook hoofdlettergevoelig, zijn die HTMLs consequent hierin?
Ja alle <TD> en <TR> "dingen" (ben ff de naam kwijt) zijn het zelfde. die mannier van inlezen ziet er nuttig uit, ik zal het morgen even gaan uitproberen.

  • beetle71
  • Registratie: Februari 2003
  • Laatst online: 04-05 09:32
Misschien een hele 'domme' opmerking, maar zo'n html filetje als je in je Topicstart zet kun je in excel gewoon openen. (In ieder geval in Excel2003) En excel converteerd 'm netjes naar een normaal werkblad.

  • kippy
  • Registratie: September 2004
  • Laatst online: 09:31
beetle71 schreef op dinsdag 08 maart 2005 @ 16:25:
Misschien een hele 'domme' opmerking, maar zo'n html filetje als je in je Topicstart zet kun je in excel gewoon openen. (In ieder geval in Excel2003) En excel converteerd 'm netjes naar een normaal werkblad.
klopt, maar op mijn werk willen ze het graag van uit een progje kunnen laden (in dit geval vb). ik zou het dan ook wel in een andere excel sheet kunnen oppenen en dan kunnen copieeren naar de juiste plek.......

maar daar heb ik nog niet echt over na gedacht... opzich geen gek idee.

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
Naar mijn idee is een welgevormde RegEx beter op zijn plaats hier dan door het bestand heen jassen met allerlei reads. Ik heb (toevallig) zojuist wat code geplaatst wat hier wel wat van weg heeft: [rml]RobIII in "[ VB6] carriage return & line feed wissen..."[/rml]

Je ziet op regel 12 een replace staan en daarna wordt het bestand weer weggeschreven. Die replace zou ik vervangen door een RegEx (Regular Expression) Replace en vervolgens het bestand wegschrijven als CSV, of desgewenst gewoon een Excel.Application object aanzwengelen en de data erin "pasten".

Wat betreft de RegEx kan ik je wel nog een beetje op weg helpen:
Visual Basic:
1
2
3
4
5
6
7
8
9
10
    Dim oRegEx as object

    Set oRegEx = fCreateObject("VBScript.RegExp")
    With oRegEx
        .IgnoreCase = True
        .Global = True
        .Pattern = "<(.|\n)+?>"
        MyString = .Replace(myString, ",")
    End With
    Set oRegEx = Nothing

Ik denk dat het pattern ( "<(.|\n)+?>" ) of de replace value ( "," ) misschien nog wat bijgeschaafd moet worden, maar allez you get my drift heh? :D

Waarschijnlijk heb je dan een tikkie sneller programma :+

De "uiteindelijke" code zou dus iets worden als:
Visual Basic:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
    Dim FF As Integer 
    Dim sTMP As String 
    Dim oRegEx as object
     
    'Bestand in 1 klap inlezen 
    FF = FreeFile                   'Vrije file handle 
    Open "C:\blabla\myfile.txt" For Binary As #FF 
    sTMP = String(LOF(FF), Chr(0))  'Init string op lengte bestand 
    Get #FF, , sTMP                 'Lees bestand in string 
    Close #FF                       'Klaar met lezen, handle vrijgeven 
     
    Set oRegEx = fCreateObject("VBScript.RegExp")
    With oRegEx
        .IgnoreCase = True
        .Global = True
        .Pattern = "<(.|\n)+?>"
        MyString = .Replace(sTMP, ",")
    End With
    Set oRegEx = Nothing

    'sTMP hier wegschrijven naar bestand (zie linkje in mijn post) of naar
    'een Excel.Application object gooien (m.b.v. een "Paste" method
    'of iets dergelijks of door de juiste .Cells te zetten)

[ Voor 46% gewijzigd door RobIII op 09-03-2005 03:23 ]

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


  • sopsop
  • Registratie: Januari 2002
  • Laatst online: 08:55

sopsop

[v] [;,,;] [v]

inhakend op de regexp methode,
Het lijkt mij dan handiger om een match te maken op <tr>xxx</tr> en <td>xxxx</td>
En dat met twee regexpjes, In quasi pseude code:
Visual Basic:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
i = 0
Set oRegEx = fCreateObject("VBScript.RegExp")
    With oRegEx
        .IgnoreCase = True
        .Global = True
        .Pattern = "\<tr\>\n?(.*?)\n?\<\/tr\>"
        .Global = True
        .IgnoreCase = True
        Set Matches = .Execute(regstr)
        For Each Match in Matches
             ' dit is nu 1 string met de <tr></tr> erin
             ' nieuwe regexp           
             redim preserve regel(i)
             Set oRegEx2 = fCreateObject("VBScript.RegExp")
             With oRegEx2
                .IgnoreCase = True
                .Global = True
                .Pattern = "\<td\>\n?(.*?)\n?\<\/td\>"
                .Global = True
                .IgnoreCase = True
                Set Matches2 = .Execute(regstr)
                For Each Match2 in Matches2
                    '  en hier heb je dus je <td></td> waarden
                    regel(i) = regel(i) & ";" & Match2.Value
                    ' je zou ook een 2 dimensionale array kunnen gebruiken, dan hoef je geen ";" als scheiding te gebruiken.
                Next
            End With
            Set oRegEx2 = Nothing
            i = i + 1
        next
    End With
Set oRegEx = Nothing

  • kippy
  • Registratie: September 2004
  • Laatst online: 09:31
boppert schreef op woensdag 09 maart 2005 @ 11:19:
inhakend op de regexp methode,
Het lijkt mij dan handiger om een match te maken op <tr>xxx</tr> en <td>xxxx</td>
En dat met twee regexpjes, In quasi pseude code:
Visual Basic:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
i = 0
Set oRegEx = fCreateObject("VBScript.RegExp")
    With oRegEx
        .IgnoreCase = True
        .Global = True
        .Pattern = "\<tr\>\n?(.*?)\n?\<\/tr\>"
        .Global = True
        .IgnoreCase = True
        Set Matches = .Execute(regstr)
        For Each Match in Matches
             ' dit is nu 1 string met de <tr></tr> erin
             ' nieuwe regexp           
             redim preserve regel(i)
             Set oRegEx2 = fCreateObject("VBScript.RegExp")
             With oRegEx2
                .IgnoreCase = True
                .Global = True
                .Pattern = "\<td\>\n?(.*?)\n?\<\/td\>"
                .Global = True
                .IgnoreCase = True
                Set Matches2 = .Execute(regstr)
                For Each Match2 in Matches2
                    '  en hier heb je dus je <td></td> waarden
                    regel(i) = regel(i) & ";" & Match2.Value
                    ' je zou ook een 2 dimensionale array kunnen gebruiken, dan hoef je geen ";" als scheiding te gebruiken.
                Next
            End With
            Set oRegEx2 = Nothing
            i = i + 1
        next
    End With
Set oRegEx = Nothing
dank dank, ik zal het vanmiddag meteen even uitproberen.

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
boppert schreef op woensdag 09 maart 2005 @ 11:19:
Visual Basic:
1
2
3
4
5
6
7
8
9
10
11
12
Set oRegEx = fCreateObject("VBScript.RegExp")
    With oRegEx
         ...
        For Each Match in Matches
            redim preserve regel(i)
             ...
             Set oRegEx2 = fCreateObject("VBScript.RegExp")
             ...
        next
         ...
    End With
Set oRegEx = Nothing
Zorg dan in ieder geval dat je niet elke keer een regex instantieert in die lus :X Tevens zie ik niet waarom je nou met arrays zou gaan moeten werken :? Die zul je dan trouwens ook nog eens god-weet-hoe-vaak moeten redimmen om "mee te groeien" naar het juiste aantal elementen (of je moet vantevoren weten hoeveel waardes je hebt, of je moet een belachelijk groot dimmen en maar hopen dat 't past :X ) Je hebt dus inderdaad gekozen voor Redim Preserve maar behalve dat dat nogal geheugenfragmentatie oplevert is het dus ook niet erg efficiënt. Replace dan meteen met die regex alle waarden. Dat is nou juist waar die dingen zo sterk in zijn. Kwestie van het juiste pattern vinden :Y)

Oh, en fCreateObject is natuurlijk je eigen functie die CreateObject "vervangt" met wat error-handling enzo neem ik aan, maar dat moet je er dan wel even bij vermelden ;)

[ Voor 114% gewijzigd door RobIII op 09-03-2005 11:40 ]

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


  • kippy
  • Registratie: September 2004
  • Laatst online: 09:31
Zorg dan in ieder geval dat je niet elke keer een regex instantieert in die lus Tevens zie ik niet waarom je nou met arrays zou gaan moeten werken Die zul je dan trouwens ook nog eens god-weet-hoe-vaak moeten redimmen om "mee te groeien" naar het juiste aantal elementen (of je moet vantevoren weten hoeveel waardes je hebt, of je moet een belachelijk groot dimmen en maar hopen dat 't past )
Ik weet hoe veel waardes er iedere keer zijn dus dit is niet echt een probleem. Ik weet nammelijk anders niet hoe ik iedere keer de waarde in een ander vakkie kan krijgen.

  • kippy
  • Registratie: September 2004
  • Laatst online: 09:31
Kan ik ook in een keer een Excel template of gewoon Excel bestand, op een "on button event" naar een van te voren ingegeven plek in een ander Excel document plakken.

Het idee is: wanneer iemand op de button "voeg meet zooi toe" drukt dat ze een menutje krijgen waar ze de kollom en rij kunnen bepalen. als ze dan op enter drukken of iet dergelijk wordt de template geladen en op de ingevoerde plaats gedumpt. Hierna kunnen ze nog de metingen toevoegen.

Ik heb wel een idee voor de rest, maar geen idee hoe ik een template op een bepaalde plek kan plakken (met de rest van de cellen ook nog goed uitgelijnd)

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
kippy schreef op woensdag 09 maart 2005 @ 13:39:
Kan ik ook in een keer een Excel template of gewoon Excel bestand, op een "on button event" naar een van te voren ingegeven plek in een ander Excel document plakken.

Het idee is: wanneer iemand op de button "voeg meet zooi toe" drukt dat ze een menutje krijgen waar ze de kollom en rij kunnen bepalen. als ze dan op enter drukken of iet dergelijk wordt de template geladen en op de ingevoerde plaats gedumpt. Hierna kunnen ze nog de metingen toevoegen.

Ik heb wel een idee voor de rest, maar geen idee hoe ik een template op een bepaalde plek kan plakken (met de rest van de cellen ook nog goed uitgelijnd)
Je vraagt wel érg veel nu. Je wil vanalles, maar ik heb het idee dat je geen flauw benul hebt waar je mee bezig bent (NOFI). Dat is niet erg, we hebben het allemaal moeten leren. Maar doe het dan rustig aan en stapje voor stapje.

Probeer eens met VB(A) te kijken of je een Excel bestand kunt openen, ga dan eens kijken of je uberhaupt iets er in kunt krijgen en ga dan kijken hoe je het op de juiste plek krijgt met de juiste uitlijning etc. Het Excel.Application object en alles daaronder is prima gedocumenteerd, er is zat over te vinden op het web en zelfs met de Macro-recorder moet je een heel eind kunnen komen.

Het is niet de bedoeling dat we alles gaan voorkauwen hier.

[ Voor 6% gewijzigd door RobIII op 09-03-2005 13:49 ]

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


  • kippy
  • Registratie: September 2004
  • Laatst online: 09:31
Ja sorry sorry. ik zit zelf niet op te letten wat ik doe.

Tis alleemaal vrij simpel, alleen mensen willen steeds dat ik het anders doe. maar het is mij al gelukt. zal nog alleen maar "moeilijke" dingen vragen :P

maar toch bedankt, denk dat ik ff pauze moet gaan houden
Pagina: 1