Avatar billede Louise1985 Mester
19. januar 2017 - 12:56 Der er 12 kommentarer og
1 løsning

Optimering af script brugt i Access

Hej alle

Jeg har fået hjælp til at lave et script som går ind og opretter rækker i en tabel i Access, hvis de ikke allerede eksisterer i forvejen.
Scriptet udfører opgaven, men på så langsom vis at med det samme jeg skalerer datagrundlaget en smule op tager den over en uge at køre... Og derudover bliver scriptet ved med at køre selvom det egentlig er udført, hvilket kræver at jeg lukker databasen ned og åbner den igen...

Har I nogle eventuelle optimeringsmuligheder til scriptet vil jeg være utrolig taknemlig.

---
Option Compare Database

Const TabelNavn = "tbl_VareforbrugStep1"
Const Varetabel = "Varenummer"

Function OpretDummyDage_AlleVarer()
  Dim d As Date
  Dim Db As Database
  Dim DummyRst As Recordset
   
  Set Db = CurrentDb
  Set DummyRst = Db.OpenRecordset("tbl_VareforbrugStep1", dbOpenSnapshot)
  With DummyRst
    If Not .EOF Then
      Do
        OpretDummyDage (!Varenummer)
        .MoveNext
      Loop Until .EOF
    End If
    .Close
  End With
  Set DummyRst = Nothing
  Set Db = Nothing
End Function

Private Sub OpretDummyDage(Varenummer As String)
  DoCmd.SetWarnings False
  For d = Date - 365 To Date
    If IsNull(DLookup("[Fysisk dato]", "tbl_VareforbrugStep1", "[Fysisk dato]=#" & Format(d, "yyyy/mm/dd") & "# AND Varenummer='" & Varenummer & "'")) Then
      DoCmd.RunSQL ("INSERT INTO tbl_VareforbrugStep1 (Varenummer, [Fysisk dato], Vareforbrug) SELECT '" & Varenummer & "',#" & Format(d, "yyyy/mm/dd") & "#, 0")
    End If
  Next d
  DoCmd.SetWarnings True
End Sub

---

Kort forklaring til hvad scriptet gør.
Jeg har en tabel med forskellige varenumre som hver har deres antal vareforbrugstransaktioner pr. dato.
F.eks.
Varenummer      Dato                    Vareforbrug (antal)
12345                13-01-2016                          10
12345                13-06-2016                          30
54321                02-03-2016                            5
54321                01-04-2016                          50
Etc.

Scriptet går ind og laver en masse fiktive transaktionsdatoer (per varenummer) med 0 stk i vareforbrug på de datoer det seneste år hvor der IKKE er transaktioner. Det skal jeg bruge i forbindelse med aggregerede udregninger såsom gennemsnitlig forbrug det seneste år pr. varenummer, standardafvigelse pr. dag pr. varenummer det seneste år osv.
Min udfordring er at jeg har 2.600 varenumre som dette skal gøres på, hvilket vil ende med at scriptet sammen med de eksisterende entries i tabellen skal skabe omkring 1 mio entries.
Det mener jeg dog ikke bør tage fem dage at køre...
Har I nogle optimeringsideer?
Pft.!

/Louise
Avatar billede terry Ekspert
19. januar 2017 - 13:18 #1
A quick calculation tells me that your creating around 1 million records, is that right?

2600 x 365
Avatar billede terry Ekspert
19. januar 2017 - 13:19 #2
;-) Yes that's right, just noticed that you mentioned that at end of text
Avatar billede terry Ekspert
19. januar 2017 - 13:20 #3
Is there any chance of seeing some test data?
Avatar billede terry Ekspert
19. januar 2017 - 13:23 #4
To test performance you could make a copy of the table without data and then just loop to insert 1 million records without doing anything else. That should give you an idea of how long that takes,
Avatar billede terry Ekspert
19. januar 2017 - 13:25 #5
anything longer than that is overhead in code
Avatar billede terry Ekspert
19. januar 2017 - 13:38 #6
In the first loop *OpretDummyDage_AlleVarer()) you open a recordset for all products

then in the next loop you use dlookup to check date, not sure exactly whats happening there. But couldn't you do this in OpretDummyDage_AlleVarer() so you only select those you know are OK date wise? That would eliminate the need to test using dlookup

Hope you understand that
Avatar billede terry Ekspert
19. januar 2017 - 13:40 #7
So instead of this
Set DummyRst = Db.OpenRecordset("tbl_VareforbrugStep1", dbOpenSnapshot)

you would open a recordset using an SQKL statement with a criteria to find only those records you will process.
Avatar billede Louise1985 Mester
19. januar 2017 - 13:54 #8
Hej Terry
Tak for fine inputs!
Jeg er på ingen måde SQL haj! Så det du beder mig om er jeg meget usikker på hvordan jeg praktisk skal gøre?
Kan du sende mig det fulde script med dine forslag til ændringer? Så prøver jeg at indsætte det og teste på et par varenumre?
Avatar billede terry Ekspert
19. januar 2017 - 14:09 #9
"Kan du sende mig det fulde script med dine forslag til ændringer" ;-)

I'd prefer you send me something I can use to test with as I have no idea of the tables /fields etc.

I only need tables code etc used in question and a bit of test data

ekspertenATsanthell.dk
AT = @
Avatar billede terry Ekspert
19. januar 2017 - 14:20 #10
Comment (idea) here #6 isn't going to work as records only exist when there are transactions for date :-(
Avatar billede Louise1985 Mester
19. januar 2017 - 14:20 #11
Hej Terry. Jeg har sendt data til din mail :)

Tak for hjælpen!

/Louise
Avatar billede Louise1985 Mester
25. januar 2017 - 14:01 #12
Vi har klaret resten via mail, men har fundet en rigtig god løsning og har nu optimeret scriptet til at blive gennemført på 2,5 time.
Avatar billede terry Ekspert
25. januar 2017 - 14:28 #13
Comment to solution.

Recordset which opened tbl_VareforbrugStep1 didn't contain distinct varenummer so a check is made to ensure we only process each varenummer once. This could be changed to an sql query which only selects DISTINCT varenummer.

A primary key comprising varenummer + date added to table so dlookup in OpretDummyDage isn't necessary, all varenummer+dates are inserted other than those which already exist
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

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