Avatar billede svjensen Nybegynder
27. august 2010 - 10:03 Der er 25 kommentarer og
1 løsning

Returner tildelt værdi fra autonummerering

Hvordan kan jeg få returneret den værdi, der indsættes i et autonummereringsfelt, så jeg kan bruge den i forbindelse med øvrige INSERT?
Avatar billede Slettet bruger
27. august 2010 - 10:09 #1
DLast("[AutoNummerFelt]";"DinTabel")
Avatar billede svjensen Nybegynder
27. august 2010 - 10:30 #2
Jeg har behov for at indarbejde det i et VBA script.
En simplificeret udgave af scriptet er vist herunder. Jeg vil så gerne have funktionen til at returnere den omtalte værdi.
Er det stadig DLast jeg skal anvende, og i så fald hvordan?

I eksemplet herunder skrives til en helt simpel tabel med to felter: uid (autonummerering) og Tekst (text)

Kode:

Const ConStr As String = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=Q:\PL\PLA\ALLE\03 Periodeplan\Sandkasse\Access programmering\TestDB.mdb;Persist Security Info=False"

Function SkrivTilDBViaSQL(Tekst As String) As Boolean
    Dim SQLstr As String
    Dim MyCon As New ADODB.Connection

    MyCon.ConnectionString = ConStr
    MyCon.Open

    SQLstr = "INSERT INTO tblTest (Tekst) VALUES ('" & Tekst & "')"
   
    MyCon.Execute SQLstr
   
    SkrivTilDBViaSQL = True
   
    'Oprydning i fht. DB
    MyCon.Close
    Set MyCon = Nothing
End Function
Avatar billede Slettet bruger
27. august 2010 - 10:41 #3
Du kan se effekten ved at sætte dette ind i slutningen af din funktion:

msgbox DLast("[uid]","tblTest")
Avatar billede svjensen Nybegynder
27. august 2010 - 10:51 #4
Det giver mig en 'Compile error: Sub or Function not defined', med 'DLast' markeret.
Avatar billede Slettet bruger
27. august 2010 - 11:26 #5
undskyld!~)

docmd.msgbox DLast("[uid]","tblTest")
Avatar billede svjensen Nybegynder
27. august 2010 - 11:41 #6
Går ud fra at det er:

MsgBox docmd.DLast("[uid]", "tblTest")
??

Det fjerner i hvertfald fejlen, men giver mig ikke nogen pop-up. Har prøvet med debug.print også, men uden held.
Avatar billede Slettet bruger
27. august 2010 - 11:46 #7
docmd.msgbox DLast("[uid]","tblTest")
Avatar billede Slettet bruger
27. august 2010 - 11:47 #8
næh... det er da ikke docmd.

lige et øjeblik, så tjekker jeg lige!~)
Avatar billede Slettet bruger
27. august 2010 - 11:55 #9
det forstår jeg ikke... mit første forslag virker fint her hos mig?~)

..altså msgbox DLast("[uid]","tblTest")

..du kan prøve DMax, men resultatet bliver nok det samme... fejlen kan måske være et andet sted, selvom den stopper ved Dlast... Kører det uden denne msgbox?~)
Avatar billede Slettet bruger
27. august 2010 - 12:16 #10
Kører du med:

Option Compare Database
Option Explicit

i starten af din modul... det er altid en god ide og kan nogle gange vise fejl, som ellers ikke ville blive opdaget!~)
Avatar billede svjensen Nybegynder
27. august 2010 - 12:21 #11
Åh, jeg tåbe.
Problemet er, at mit script kører i excel, da data skal importeres fra regneark.
Så spørgsmålet er i virkeligheden stillet i den forkerte kategori.
Det beklager jeg :-)

Ved du tilfælgdivis, hvordan jeg kan få returneret værdien i excel VBA?
Avatar billede Slettet bruger
27. august 2010 - 12:42 #12
Nej!~)
Avatar billede svjensen Nybegynder
27. august 2010 - 12:48 #13
OK. Tak for din tid. Jeg beklager, at det var forgæves :-)

/Søren
Avatar billede svjensen Nybegynder
27. august 2010 - 12:53 #14
Lukker
Avatar billede svjensen Nybegynder
27. august 2010 - 13:10 #15
Fik hul igennem fra excel vha.:

Access.Application.DLast("[uid]", "tblTest")

Men den returnerer værdien fra den sidste post inden jeg skriver til tabellen.
Hvis posten inden har uid 6, og jeg via scriptet skriver til tabellen og den angiver uid til 7, så returnerer DLast altså 6.
Og det er jo ikke lige det jeg har brug for...

Kan vi køre den videre her, eller skal jeg oprette et nyt spørgsmål?
Avatar billede Slettet bruger
27. august 2010 - 13:16 #16
kører du den efter:

MyCon.Execute SQLstr
Avatar billede svjensen Nybegynder
27. august 2010 - 13:24 #17
Ja. Den kommer lige efter:
SkrivTilDBViaSQL = True
Avatar billede Slettet bruger
29. august 2010 - 12:02 #18
DLAST kommentar:

Advaret, først beskrivelsen i f1-hjælpen og derefter af Duane Hookom i

http://www.pcreview.co.uk/forums/thread-1681342.php

testede jeg med:

Sub testdlast()
    Dim bigfield, id As Long, dlastV
    bigfield = String(32768, 65)
   
    CurrentDb.Execute "create table dlasttest (id autoincrement not null,fillField memo,constraint dlasttest_PK primary key(id))"
    Do
        id = id + 1
        CurrentDb.Execute "insert into dlasttest(fillField) values(""" & bigfield & """)"
        If id Mod 10 = 0 Then
            CurrentDb.Execute "delete from dlasttest where id < " & Int(id * 0.8)
            Debug.Print "less than " & Int(id * 0.8) & " is deleted": End If
        dlastV = dlast("id", "dlasttest")
    Loop Until id <> dlastV
    Debug.Print "Dlast() returned: " & dlastV & " after inserting autonumber:" & id
   
End Sub

---

Tilmed vil fejlens konsekvens ofte være join af forkerte ting - fejldata - en type fejl der kan være svær at finde årsag til hvis man ikke har en mistanke.
Avatar billede svjensen Nybegynder
29. august 2010 - 14:31 #19
Det bekræfter jo mit problem :-)
Jeg har i øvrigt prøvet med DMax også, men det gav faktisk lidt samme problem. Hvis jeg anvender det i samme script, hvori jeg skriver til tabellen, så medtager den ikke den sidste entry.
Og da jeg netop har behov for at vide, hvilken værdi denne er tildelt (da jeg skal bruge den til andre tabeller), så er jeg lige vidt.

Er der andre forslag til, hvordan jeg kan få returneret værdien?
Avatar billede Slettet bruger
29. august 2010 - 15:18 #20
Jeg vil mene at det er garanteret at en insert statement, i ms-access, der ikke explicit tildeler autonummer feltet værdi, afstedkommer at autonummer får værdien 1 højere end højeste før indsættelse.
Dette gælder også selv om der har været explicite tildelinger med lavere værdier i 'ledige huller' - autonumber counteren forbliver på 'max'.

dmax ligesom de andre d<aggreate> ting er bekvemme ms-access vba funktion overbygninger på de almindelige sql aggreate funktioner: min,max,count,sum,.....

i #2 tilgåes datakilden fra adodb (fra excel erfarer vi senere) - jeg ville holde mig til samme tilgangsmåde og lave en select max(<autonumber field name>) query.

Begrundelsen er at det ikke er til at vide hvornår forskellige lag af buffering flushes, men holder man sig indenfor samme tilgangsmåde må man forvente at det fra producentens side er implementeret på den brugbar måde.
Avatar billede svjensen Nybegynder
30. august 2010 - 11:01 #21
Tilsyneladende er der hjælp at hente her:
http://databases.aspfaq.com/general/how-do-i-get-the-identity/autonumber-value-for-the-row-i-inserted.html

Men jeg er usikker på, hvordan jeg kan indarbejde det i min VBA kode.
Avatar billede Slettet bruger
30. august 2010 - 11:50 #22
#2 omskrevet til kodeeksemplet lidt nede i det linket i #21 henvider til, forudsat dit autonumber felt hedder 'id'. Funktionen SkrivTilDBViaSQL retunerer nu den nye id.



Function SkrivTilDBViaSQL(tekst As String) As Boolean
    Dim SQLstr As String
    Dim MyCon As New ADODB.Connection
    Dim rs As ADODB.Recordset

    MyCon.ConnectionString = ConStr
    MyCon.Open

    SQLstr = "INSERT INTO tblTest (Tekst) VALUES ('" & tekst & "')"
 
    Set rs = MyCon.Execute(SQLstr)
 
    SkrivTilDBViaSQL = rs("id") ' rs(0)
 
    'Oprydning i fht. DB
    MyCon.Close
    Set MyCon = Nothing
End Function
Avatar billede svjensen Nybegynder
30. august 2010 - 12:21 #23
Mangler der ikke noget i SQL sætningen?
I linket i #21 anvendes 'SELECT @@IDENTITY'.

Jeg har prøvet at indsætte det, men kan ikke helt få det til at lykkes.
Avatar billede Slettet bruger
30. august 2010 - 13:48 #24
Jo, det har du ret i - jeg har læst det som fanden læser bibelen!

Måske skal tabellen være skabt med den indentity ting, som antydet i :
"CREATE TABLE AutoIncrementTest " & _
            "(ID int identity, Description varchar(40), " & _
            "CONSTRAINT AutoIncrementTest_PrimaryKey PRIMARY KEY (ID))"

fra linket:
http://support.microsoft.com/kb/232144/en-us

Ellers prøv eksemplet under fra linket i #21, hvor der efterfølgende særskilt hentes med 'select max(id) .....'
Avatar billede svjensen Nybegynder
30. august 2010 - 14:04 #25
Det prøver jeg at kigge nærmere på.
Indtil videre har jeg fået det til at virke vha. af nedenstående, som er en lidt anden tilgang.


Sub ADOFromExcelToAccess()
' exports data from the active worksheet to a table in an Access database
' this procedure must be edited before use
Dim cn As ADODB.Connection, rs As ADODB.Recordset, r As Long
Dim pk As Long
    ' connect to the Access database
    Set cn = New ADODB.Connection
    cn.Open "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=Q:\PL\PLA\ALLE\03 Periodeplan\Sandkasse\Access programmering\TestDB.mdb;Persist Security Info=False"
    ' open a recordset
    Set rs = New ADODB.Recordset
    rs.Open "tblTest", cn, adOpenKeyset, adLockOptimistic, adCmdTable
    ' all records in a table
        With rs
            .AddNew ' create a new record
            ' add values to each field in the record
            .Fields("Tekst") = "Kurt"
'            .Fields("FieldName2") = Range("B" & r).Value
'            .Fields("FieldNameN") = Range("C" & r).Value
            ' add more fields if necessary...
            .Update ' stores the new record
            pk = .Fields("uid")
        End With
    Debug.Print pk
    rs.Close
    Set rs = Nothing
    cn.Close
    Set cn = Nothing
End Sub
Avatar billede Slettet bruger
30. august 2010 - 19:50 #26
Det er ligeså godt med recordset methods som noget andet - og udmærket at du fik præsenteret forskellige metoder.
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
Dyk ned i databasernes verden på et af vores praksisnære Access-kurser

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