Avatar billede hubs Nybegynder
24. november 2003 - 12:48 Der er 26 kommentarer og
1 løsning

Import fra excel til access

Ohøøøj!

Jeg har lavet en Råmateriale DB i Access 2002, hvor jeg bl.a. importere div. kemiske analyser fra excel. De kemiske analyser har deres egen tabel som er forbundet via en Mange-til-En relation til en tabel der indeholder general information om det enkelte råmaterialer. Jeg bruger "DoCmd.TransferSpreadsheet" til at importere og det virker fint, men kun så længe at jeg importere en analyse af et råmateriale der allerede findes i DB'en.

Jeg har derfor brug for at kunne kontrollere om råmateriale navnet på den pågældende Kemiske Analyse allerede findes i min råmaterialetabel inden jeg importere hele analysen. NB. Råmateriale navnet er altid i celle 'A2! i mit excelsheet.

Det er første gang jeg bruger eksperten, så jeg håber at mit spørgsmål er til at forstå.
Avatar billede monnypenny Nybegynder
24. november 2003 - 13:37 #1
Dvs. du skal kontrollere at det navn der står i calle A2 findes i din database. Det skulle nok kunne lade sig gøre...

Prøv at vis lidt af din kode, så er det nemmere at komme med forslag, der passer ind i det du allerede har lavet...
Avatar billede hubs Nybegynder
24. november 2003 - 13:48 #2
Jeg bruger iøjeblikket følgende kode til at importere

Private Sub Import_Excel_1_Click()

    Screen.MousePointer = 11

    DoCmd.TransferSpreadsheet acImport, 0, "Chemical Analysis 2", "C:\Excel\ImportTemplate.xls", True, "A1:AN2"
    DoCmd.DoMenuItem acFormBar, acRecordsMenu, 5, , acMenuVer70
    MsgBox "Import Completed."

    Screen.MousePointer = 0
End Sub
Avatar billede hubs Nybegynder
24. november 2003 - 13:56 #3
jeg ville gerne ha noget i retning af.

If "råmaterialenavn findes i [RawMaterial]" Then
  DoCmd.OpenForm "indtast Info" ' Her Kan brugeren indtaste de nødvendige info så jeg kan oprette en record med det nye råmaterialenavn inden analysen importeres...
  DoCmd.TransferSpreadsheet...
else
  DoCmd.TransferSpreadsheet...
Avatar billede hubs Nybegynder
24. november 2003 - 14:16 #4
Jeg har også prøvet med først at importere råmaterialenavnet først (se nedenfor), men det giver så bare problemer hvis navnet allerede findes fordi det samme råmateriale ikke kan være der to gange...

DoCmd.TransferSpreadsheet acImport, 0, "Material Information", "C:\Excel\ImportTemplate.xls", True, "A1:A2"
Avatar billede martin_moth Mester
24. november 2003 - 14:33 #5
Kan du ikke lave et almindeligt udtræk fra databasen med en SQL-statement, og så tjekke om recordsettet der returneres er tomt. Er det det, findes det ikke i databasen, og du afbryder din sub. Er recordsettet ikke tomt, importerer du så som du ellers ville gøre.

Der er garanteret en smartere måde
Avatar billede hubs Nybegynder
24. november 2003 - 14:40 #6
Det lyder i hvert fald som en mulighed... Er det muligt at importere Råmateriale navnet fra excel direkte til en variable så jeg kan bruge den i min SQL eller skal det importeres til en tabel først??
Avatar billede martin_moth Mester
24. november 2003 - 14:46 #7
Noget i den stil

    Dim objConn As ADODB.Connection
    Dim objRs As ADODB.Recordset
    Dim strConnString As String
    Dim strSQL As String

    Set objConn = New ADODB.Connection
    Set objRs = New ADODB.Recordset
   
    strConnString = "DRIVER={Microsoft Access Driver (*.mdb)}; DBQ=C:\Database.mdb"
    objConn.Open strConnString
   
    strSQL = "SELECT råmateriale FROM råmaterialetabel WHERE råmaterialenavn = " & activesheet.range("A1").Value  'Denne linie skal rettes!!!!
    objRs.Open strSQL, objConn
  If not objRs.EOF Then 'Hvis EOF er recordsettet tomt. Man kan også tjekke på andre måder end EOF
    msgbox "Post findes i forvejen"
    exit sub
  Else
    'Gør hvad du vil hvis det ikke findes i forvejen 
  End if
  objRs.Close
  objConn.Close
Avatar billede hubs Nybegynder
24. november 2003 - 14:49 #8
Det ser meget lovende ud. Jeg tester det lige igennem og vender hurtigst muligt tilbage :o)
Avatar billede martin_moth Mester
24. november 2003 - 14:57 #9
Jeg ville nok læse værdien an A1 ind i en stringvariabel, og så bruge den stringvariabel i min connectionstring...
Avatar billede hubs Nybegynder
24. november 2003 - 15:05 #10
Jeg får fejlen "[ODBC Microsoft Access Driver] Too few parameters. Expected 1."
Avatar billede martin_moth Mester
24. november 2003 - 15:20 #11
Der er 1000 eksempler på forskellige connectionstrings på eksperten. Jeg kopierede bare fra et andet svar og omskrev. Her er en anden måde:

  Dim rec As Recordset
  Dim DB as Database 

  Set DB = Workspaces(0).OpenDatabase("C:\database.mdb")
  Set rec = DB.OpenRecordset _
    ("SELECT Række1, Række2, Række3 FROM Tabel ORDER BY Række1", _
            dbOpenSnapshot)
 
  'Række1, Række2,... og Tabel er navne angivet i din database

  Herefter indeholder rec dit recordsæt, og du kan teste på om det er tomt
Avatar billede hubs Nybegynder
24. november 2003 - 15:22 #12
Den tilpassede kode ser sådan her ud, men jeg får som sagt ovenstående fejl... nogen idéer???

    Dim objConn As ADODB.Connection
    Dim objRs As ADODB.Recordset
    Dim strConnString As String
    Dim strSQL As String

    Set objConn = New ADODB.Connection
    Set objRs = New ADODB.Recordset
   
    strConnString = "DRIVER={Microsoft Access Driver (*.mdb)}; DBQ=C:\Research\test.mdb"
    objConn.Open strConnString
   
    strSQL = "SELECT RawMaterialName FROM [Material Information] WHERE RawMaterialName = " & ActiveSheet.Range("A2").Value
    objRs.Open strSQL, objConn
 
  If Not objRs.EOF Then
    MsgBox "Post findes i forvejen"
    Exit Sub
  Else
    MsgBox "Post findes ikke"
  End If
 
  objRs.Close
  objConn.Close
Avatar billede martin_moth Mester
24. november 2003 - 15:28 #13
Prøv at skifte de par linier hvor du hooker op til databasen med dem jeg har skitseret ovenfor
Avatar billede hubs Nybegynder
24. november 2003 - 15:31 #14
Nu får jeg følgende fejl "Object variable or With Block not set" hvilket forekommer mig lidt underligt... eller er det bare mig
Avatar billede hubs Nybegynder
24. november 2003 - 15:34 #15
Jeg bliver desværre nød til at humle for i dag, men er tilbage i morgen tidlig... foreløbig tak for hjælpen jeg er sikker på at det nok skal lykkedes.. :o) Fortsat god dag..

Jacob
Avatar billede martin_moth Mester
24. november 2003 - 15:40 #16
Det er jeg også sikker på. Du kan evt. finde inspiration ved at søge på fx. "Database" - om du linker til en database fra VB eller VBA er principielt ligegyldigt...
Avatar billede martin_moth Mester
24. november 2003 - 15:56 #17
Hvad får du af fejl, hvis du prøver nedenstående:

  Dim rec As Recordset
  Dim DB as Database 
  Dim strKriterium as String
  strKriterium = ActiveSheet.Range("A2").Value

  strSQL = "SELECT RawMaterialName FROM [Material Information] WHERE _
          RawMaterialName = " & ActiveSheet.Range("A2").Value
  Set DB = Workspaces(0).OpenDatabase("C:\database.mdb")
  Set rec = DB.OpenRecordset _
            "SELECT RawMaterialName FROM [Material Information] WHERE _
            RawMaterialName = " & strKriterium, _
            dbOpenSnapshot)

  If Not Rec.EOF Then
    MsgBox "Post findes i forvejen"
    Exit Sub
  Else
    MsgBox "Post findes ikke"
  End If
 
  Rec.Close
  DB.Close
  Set Rec = nothing
  Set DB = Nothing
Avatar billede bak Forsker
24. november 2003 - 21:27 #18
Dette er kun et eksempel på hvorledes det kunne gøres, med en connection string til excel.

Public Sub QueryWorksheet()

    Dim rsData As ADODB.Recordset
    Dim szConnect As String
    Dim szSQL As String
   
    ' opret connection string.
  'Totalsalg.xls er filnavnet
    szConnect = "Provider=Microsoft.Jet.OLEDB.4.0;" & _
                "Data Source=C:\totalsalg.xls;" & _
                "Extended Properties=Excel 8.0;"
   
  'SalgNovember er arknavnet
    szSQL = "SELECT * FROM [SalgNovember$A1:a2]"
 
    Set rsData = New ADODB.Recordset
    rsData.Open szSQL, szConnect, adOpenForwardOnly, _
                adLockReadOnly, adCmdText
   
    ' Check to make sure we received data.
    If Not rsData.EOF Then
        MsgBox "Data modtaget"
        Debug.Print rsData.Fields(0)
    Else
        MsgBox "Ingen data modtaget.", vbCritical
    End If
   
    ' Clean up our Recordset object.
    rsData.Close
    Set rsData = Nothing

End Sub
Avatar billede hubs Nybegynder
25. november 2003 - 09:16 #19
>> Martin Moth >> Det giver desværre samme fejl som før "Too few parameters. Expected 1." og hvis jeg roder lidt rundt med det kommer fejlen "Object variable or With Block not set" igen, som dog forsvinder igen hvis jeg genstarter Db'en...
Avatar billede martin_moth Mester
25. november 2003 - 09:56 #20
Du skal ikke have databasen åben!
Avatar billede hubs Nybegynder
25. november 2003 - 10:06 #21
skal databasen ikke være åben?? jeg forstår vist ikke helt hvad du mener, det er jo fra Db'en at brugeren trykker på en knap for at importere fra Excel...
Jeg har prøvet at ændre noget af din kode til følgende, men får stadigvæk "Too few Parameters. Expected 1." og jeg kan desværre kun trykke 'Ok' ved fejlen :o(

strSQL = "SELECT RawMaterialName FROM [Material Information] WHERE _ RawMaterialName = " & ActiveSheet.Range("A2").Value
Set rec = CurrentDb.OpenRecordset(strSQL, dbOpenSnapshot)
Avatar billede martin_moth Mester
25. november 2003 - 10:18 #22
For f... da. Jeg har misforstået!!! Troede du skulle hente fra en database ind i excel (selvom du tydeligt har skrevet det modsatte. Beklager)....

Dvs: For at skære det ud i pap:

Du er i din database, og skal via VBA hente noget data fra Excel over i databasen. Det klarer du selv fint.
Men hvis det navn der står i regnearkets celle A2 allerede findes i databasen, skal der IKKE hentes data fra Excel.... Så problemet er, at læse celle A2 fra regnearket (det har sjh vist vist ovenfor) og så tjekke om de data findes i forvejen i databasen...?

Jeg har aldrig brugt VBA i Access, kun den anden vej, så måske skal en anden tage over...

Beklager at jeg ikke bare læste spørgsmålet ordentligt...
Avatar billede hubs Nybegynder
25. november 2003 - 10:36 #23
Yeps det er lige nøjagtigt mit problem, du beskriver det noget bedre end jeg kunne :o)

Uanset hvad så har du været en stor hjælp så du skal nok få points, Jeg får hentet den rigtige data og den bruger de rigtige søgekriterier, men der må være et eller andet galt med Set rec =... sætningen, det er umiddelbart her fejlen opstår og jeg kan ved den søde grød ikke se hvorfor... meget frustrerende
Avatar billede martin_moth Mester
25. november 2003 - 11:12 #24
Jeg tror at du kan tjekke det meget nemmere. Det jeg har foreslået går på hvordan du tjekker om noget er i en database fra et ANDET program, fx. fra Excel, word eller noget andet. Når du vil tjekke med en vba-macro fra selve ACCESS, er der garanteret en 100 gange lettere måde. Men det ved jeg desværre ikke noget om... Et GÆT kunne være:

If activeDatabase.Record("recordnavn").recordcount = 0 then ... Efter fri fantasi...

Nu kan jeg se at du har givet mig points (mange tak, men det var nu ikke fortjent) - og så er der nok ikke andre der gider hjælpe ;o)

Prøv at start et nyt spørgsmål, og se om der ikke er nogen der hjælper. Præciser, at det altså er VBA i Access du bruger :o)
Avatar billede bak Forsker
25. november 2003 - 20:56 #25
hubs, har du testet min kode med dine egne data ?
Den er jo netop beregnet til at køre fra Access og forespørge i Excel med en sql-query
Avatar billede hubs Nybegynder
26. november 2003 - 09:58 #26
bak >> Jeg har ikke prøvet din kode, men jeg kan sagtens få de rigtige data ud fra excel med "ActiveSheet.Range("A2").Value" mit problem er at den "nægter" at køre min query i "set rec =..." sætningen.

Det underlige er at jeg bruger nøjagtigt den samme recordset sætning tidligere i min code og den virker upåklageligt, mildt sagt MEGET frustrerende
Avatar billede hubs Nybegynder
26. november 2003 - 10:33 #27
Splitte mine bramsejl, så fandt jeg sku fejlen. Når man bruger WHERE i SQL strengen så skal den efterfølgende variable være omgivet af apostroffer...

Result:
strSQL = "SELECT RawMaterialName FROM [Material Information] WHERE _ RawMaterialName = '" & ActiveSheet.Range("A2").Value & "'"

Tusind tak for jeres hjælp
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
Kurser inden for grundlæggende programmering

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