Avatar billede jjs_new Nybegynder
17. marts 2004 - 08:24 Der er 18 kommentarer og
1 løsning

Data fra Access til Excel

Hejsa

Jeg har et regneark som består at et "varenummer" og en "2003pris". I en access database har jeg samme "varenummer" og en "2004pris". Udfordringen består i at kæde data fra min access database sammen med data fra mit Excel regneark.

Da min Access database består af ca. 200000 poster, ville jeg gerne undgå at skulle indsætte alle disse poster i et regne ark, hver gang der kom en ny database med nye priser. Derfor ser en en løsning i retning af en makro, som er istand til at læse værdien varenummer i A1, A2, A3.. osv.(evt. between) og dermed lave et SQL statement som kan slå prisen op i access og aflevere resultatet i celle C1, C2, C3 osv ..

Jeg fandt denne makro herinde, som måske kan hjælpe på vej :-)

Sub GetTable()
  Dim Db As Database
  Dim Rs As Recordset
  Dim Ws As Worksheet
  Dim Path As String
  Set Ws = ActiveSheet
  Dim sqlstr As String

  '*** sti til database ***
  Path = "D:\db1.mdb"    'Her indsætter du navn og sti på din accessdatabase

  '*** SQL-streng med reference til A2 ***
  '**** dvs at den skal finde den record i access hvor Varenummeret er lig med det du har skrevet i A1
  sqlstr = "SELECT * FROM 2004 WHERE DESCP =" & Range("A2").Value & ";"


  '*** Hent data ***
  Set Db = Workspaces(0).OpenDatabase(Path, ReadOnly:=True)
  Set Rs = Db.OpenRecordset(sqlstr)
 
'*** Indsæt VareTekst i A5 og Disponent i A7 ***
  Ws.Range("G2") = Rs.Fields("DESCP")
  Ws.Range("H2") = Rs.Fields("EPL2004")

  '*** luk databasen igen ***
  Rs.Close
  Db.Close
End Sub

Mvh
Jan
Avatar billede jjs_new Nybegynder
17. marts 2004 - 08:26 #1
For en god ordens skyld hedder min tabel i Access DB'en "2004", felterne hedder "DESCP"=Varenummer og "EPL2004"=pris 2004.

/Jan
17. marts 2004 - 09:17 #2
Ja, den kan godt bruges som udgangspunkt. Jeg kigger lige lidt på det.
17. marts 2004 - 09:30 #3
Flere ting i nedenstående skal skiftes ud
- Ret stien og navnet på databasen
- Ret tabelnavn (et sted)
- Ret feltnavn (to steder)
- Skal prisen ikke indsættes i kolonne B men f.eks. i D - så ret Offset(0, 1) til Offset(0, 3)

Sub GetPrices()
    Dim dbPrice As Database
    Dim rsData As Recordset
    Dim sPath As String
    Dim sSQL As String
    Dim sSQLTemp As String
    Dim rCell As Range
   
    '*** sti til database ***
    sPath = "D:\db1.mdb"    'Her indsætter du navn og sti på din accessdatabase
   
    '*** SQL-streng hvor XXX bliver udskiftet ***
    sSQL = "SELECT * FROM tabelnavn WHERE feltnavn = XXX;"
   
    For Each rCell In ActiveSheet.UsedRange.Columns(1).Cells
       
        '*** SQL sætning ***
        sSQLTemp = Replace(sSQL, "XXX", rCell.Value)
       
        '*** Hent data ***
        Set dbPrice = Workspaces(0).OpenDatabase(sPath, ReadOnly:=True)
        Set rsData = dbPrice.OpenRecordset(sSQLTemp)
       
        '*** Indsæt pris i kolonne B ***
        rCell.Offset(0, 1).Value = rsData.fields("feltnavn").Value
       
        '*** Luk recordset ***
        rsData.Close

    Next rCell
   
    '*** luk databasen igen ***
    dbPrice.Close
   
    '*** Ryd op ***
    Set rCell = Nothing
    Set Rs = Nothing
    Set Db = Nothing
End Sub
Avatar billede jjs_new Nybegynder
17. marts 2004 - 09:51 #4
Takker mange gange for svaret!!

Men jeg har et lille problem, da den fejler ved: sSQLTemp = Replace(sSQL, "XXX", rCell.Value).

Noget i retningen af "Der var for få parametre 0, ventet 1" og error en "3061"??

Den fik også denne fejl i den oprindelige kode jeg postede .. gør jeg noget galt?

/Jan
Avatar billede jjs_new Nybegynder
17. marts 2004 - 09:58 #5
Sorry det er denne linie der gir problemet ... fejlen er den samme :-) : Set rsData = dbPrice.OpenRecordset(sSQLTemp)

/Jan
17. marts 2004 - 10:06 #6
Ja, der vil sikkert være nogle problemstillinger, som kan give fejl....

Jeg har ikke tid til at kigge yderligere på det nu, men du er velkommen til at sende arket til mig med henvisning til spørgsmålnummeret, så vil jeg kigge på det i aften.
Find min email her www.win-consult.com.
17. marts 2004 - 17:12 #7
Sub GetPrices()
    Dim dbPrice As Database
    Dim rsData As Recordset
    Dim sPath As String
    Dim sSQL As String
    Dim sSQLTemp As String
    Dim rCell As Range
   
    '*** sti til database ***
    sPath = "D:\VBA-Test\Jan Schneider\db1.mdb"    'Her indsætter du navn og sti på din accessdatabase
   
    '*** SQL-streng hvor XXX bliver udskiftet ***
    sSQL = "SELECT * FROM 2004 WHERE DESCP = 'XXX';"
   
    For Each rCell In ActiveSheet.UsedRange.Columns(1).Cells
       
        '*** SQL sætning ***
        sSQLTemp = Replace(sSQL, "XXX", rCell.Value)
       
        '*** Hent data ***
        Set dbPrice = Workspaces(0).OpenDatabase(sPath, ReadOnly:=True)
        Set rsData = dbPrice.OpenRecordset(sSQLTemp)
       
        '*** Indsæt pris i kolonne B ***
        If Not rsData.RecordCount = 0 Then
            rCell.Offset(0, 3).Value = rsData.Fields("EPL2004").Value
        End If
        '*** Luk recordset ***
        rsData.Close

    Next rCell
   
    '*** luk databasen igen ***
    dbPrice.Close
   
    '*** Ryd op ***
    Set rCell = Nothing
    Set Rs = Nothing
    Set Db = Nothing
End Sub
Avatar billede bak Forsker
17. marts 2004 - 17:25 #8
Er den ikke langsom, flemming..?
Jeg har ikke testet, men det ser ud til at du laver mange sql-udtræk og det må da koste kræfter.
Avatar billede bak Forsker
17. marts 2004 - 17:33 #9
Det kunne måske misforståes. Det er absolut ikke ment som kritik.
Jeg mener bare at man burde kunne nøjes med at hente det hele een gang og derefter gøre noget smart.
17. marts 2004 - 19:38 #10
Rigtigt bak - anhængigt af mængden af priser, og jeg ville nok også hente alt i et hug selv.
17. marts 2004 - 19:49 #11
Nok noget alla dette:

Sub GetPrices()
    Dim dbPrice As Database
    Dim rsData As Recordset
    Dim sPath As String
    Dim sSQL As String
    Dim rCell As Range
    Dim lRecord As Long
   
    '*** sti til database ***
    sPath = "D:\VBA-Test\Jan Schneider\db1.mdb"    'Her indsætter du navn og sti på din accessdatabase
   
    '*** SQL-streng hvor XXX bliver udskiftet ***
    sSQL = "SELECT * FROM 2004;"
   
    '*** Hent data ***
    Set dbPrice = Workspaces(0).OpenDatabase(sPath, ReadOnly:=True)
    Set rsData = dbPrice.OpenRecordset(sSQL)
   
    If Not rsData.RecordCount = 0 Then
        For Each rCell In ActiveSheet.UsedRange.Columns(1).Cells
           
            rsData.MoveFirst
            Do While Not rsData.EOF
                If rCell.Value = rsData.Fields("DESCP").Value Then
                    rCell.Offset(0, 3).Value = rsData.Fields("EPL2004").Value
                    Exit Do
                End If
                rsData.MoveNext
            Loop
           
        Next rCell
    End If

    '*** luk databasen igen ***
    rsData.Close
    dbPrice.Close
   
    '*** Ryd op ***
    Set rCell = Nothing
    Set rsData = Nothing
    Set dbPrice = Nothing
End Sub
Avatar billede bak Forsker
17. marts 2004 - 20:16 #12
Istedet for at move igennem kunne man måske benytte .find
Jeg har fået det til at virke, men synes ukke at hastighed imponerer (nu skal der også meget til :-)  )

teststr = "DESCP = '" & rCells.value & "'"
rsData.Find teststr, , adSearchForward, 1
If rsData.EOF Then
  rCell = "not found"
  rsData.MoveFirst
Else
  rCell = rsData!ELP2004
End If

Jeg har forsøgt med rsdata.seek som skulle være meget hurtig, men kan ikke rigtig komme ind på den...
Avatar billede bak Forsker
17. marts 2004 - 20:16 #13
ukke = ikke
Avatar billede bak Forsker
17. marts 2004 - 20:18 #14
Sorry igen

teststr = "DESCP = '" & rCells.value & "'"
rsData.Find teststr, , adSearchForward, 1
If rsData.EOF Then
  rCell = "not found"
  rsData.MoveFirst
Else
  rCell.Offset(0, 3).Value  = rsData!ELP2004
End If
17. marts 2004 - 20:28 #15
Ja, det kan man godt. Dog synes jeg at gennemløb af data, som du har i et objekt er så hurtig, at der ikke vindes proformance ved at gøre det anderledes. Mængden af data kan selvfølgelig blive SÅ stor, at det måske kan mærkes.
Avatar billede jjs_new Nybegynder
18. marts 2004 - 08:12 #16
Takker mange gange Flemming!! Det var lige hvad der skulle til :-)

Mvh
Jan
Avatar billede jjs_new Nybegynder
18. marts 2004 - 10:04 #17
Hej Igen

Lige en kommentar!

Det viser sig at det bedre kan betale sig at lave flere SQL forspørgsler, frem for at læse hele databasen ind i et object! Min DB fylder 26Mb (250000 poster)komprimeret og optimeret og det tager derfor evigheder at læse det hele det hele ind. Benytter jeg den først forslåede metode sker det hele i en ruff .. næsten :-)


/Jan
Avatar billede bak Forsker
18. marts 2004 - 10:06 #18
Tak for tilbagemeldingen. Det er altid rart at vide, hvis man selv skal lave noget lignende engang.
18. marts 2004 - 10:42 #19
Super - bemærk blot, at der er en fejl under RYD OP i den makro, som laver mange SQL-forespørgsler. Det skal se således ud:

    '*** Ryd op ***
    Set rCell = Nothing
    Set rsData = Nothing
    Set dbPrice = Nothing
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Vi har et stort udvalg af Excel kurser. Find lige det kursus der passer dig lige her.

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester