Avatar billede jind Nybegynder
22. juni 2008 - 14:02 Der er 23 kommentarer og
2 løsninger

Backup mens databasen bruges

Hej I gæve xperter,
Jeg har prøvet at lave en knap der kan kopiere nogle back ends til en backupmappe. Desværre kommer der en fejl med at "permission denied" hvis databasen er i brug af en anden.

Nogen ideer til havd man gør?

PS. jeg kan godt stå i stifinder og copy/paste uden problemer.

Tak for den hjælp jeg kan få..


VH jind
Avatar billede terry Ekspert
22. juni 2008 - 14:11 #1
What code are yousuing to make the backup?

Normally I woulnt have thought there would be any problem making a copy of a file (access dB) even if it is in use.
Avatar billede Slettet bruger
22. juni 2008 - 17:37 #2
filecopy du'r ikke hvis filen er i brug, her er en funktion, som jeg bruger til at tage backup af en db, som er i brug:

Du kalder den med Call fMakeBackup


Option Compare Database
Option Explicit

Private Type SHFILEOPSTRUCT
    hwnd As Long
    wFunc As Long
    pFrom As String
    pTo As String
    fFlags As Integer
    fAnyOperationsAborted As Boolean
    hNameMappings As Long
    lpszProgressTitle As String
End Type

Private Const FO_MOVE As Long = &H1
Private Const FO_COPY As Long = &H2
Private Const FO_DELETE As Long = &H3
Private Const FO_RENAME As Long = &H4

Private Const FOF_MULTIDESTFILES As Long = &H1
Private Const FOF_CONFIRMMOUSE As Long = &H2
Private Const FOF_SILENT As Long = &H4
Private Const FOF_RENAMEONCOLLISION As Long = &H8
Private Const FOF_NOCONFIRMATION As Long = &H10
Private Const FOF_WANTMAPPINGHANDLE As Long = &H20
Private Const FOF_CREATEPROGRESSDLG As Long = &H0
Private Const FOF_ALLOWUNDO As Long = &H40
Private Const FOF_FILESONLY As Long = &H80
Private Const FOF_SIMPLEPROGRESS As Long = &H100
Private Const FOF_NOCONFIRMMKDIR As Long = &H200

Private Declare Function apiSHFileOperation Lib "Shell32.dll" _
            Alias "SHFileOperationA" _
            (lpFileOp As SHFILEOPSTRUCT) _
            As Long

Function fMakeBackup() As Boolean
Dim strMsg As String
Dim tshFileOp As SHFILEOPSTRUCT
Dim lngRet As Long
Dim strSaveFile As String
Dim lngFlags As Long
Const cERR_USER_CANCEL = vbObjectError + 1
Const cERR_DB_EXCLUSIVE = vbObjectError + 2
    On Local Error GoTo fMakeBackup_Err

    If fDBExclusive = True Then Err.Raise cERR_DB_EXCLUSIVE
   
    strMsg = "Er du sikker på at du vil lave et kopi af databasen?"
    If MsgBox(strMsg, vbQuestion + vbYesNo) = vbNo Then _
            Err.Raise cERR_USER_CANCEL
           
    'lngFlags = FOF_SIMPLEPROGRESS Or _
    '                        FOF_FILESONLY Or _
    '                        FOF_RENAMEONCOLLISION
    'strSaveFile = CurrentDb.Name
   
    lngFlags = FOF_SIMPLEPROGRESS Or _
                            FOF_FILESONLY
    strSaveFile = "c:\backup\DinDatabase.mdb"
   
   
   
   
    With tshFileOp
        .wFunc = FO_COPY
        .hwnd = hWndAccessApp
        .pFrom = CurrentDb.Name & vbNullChar
        .pTo = strSaveFile & vbNullChar
        .fFlags = lngFlags
    End With
    lngRet = apiSHFileOperation(tshFileOp)
    fMakeBackup = (lngRet = 0)
   
fMakeBackup_End:
    Exit Function
fMakeBackup_Err:
    fMakeBackup = False
    Select Case Err.Number
        Case cERR_USER_CANCEL:
            'do nothing
        Case cERR_DB_EXCLUSIVE:
            MsgBox "The current database " & vbCrLf & CurrentDb.Name & vbCrLf & _
                    vbCrLf & "is opened exclusively.  Please reopen in shared mode" & _
                    " and try again.", vbCritical + vbOKOnly, "Database copy failed"
        Case Else:
            strMsg = "Error Information..." & vbCrLf & vbCrLf
            strMsg = strMsg & "Function: fMakeBackup" & vbCrLf
            strMsg = strMsg & "Description: " & Err.Description & vbCrLf
            strMsg = strMsg & "Error #: " & Format$(Err.Number) & vbCrLf
            MsgBox strMsg, vbInformation, "fMakeBackup"
    End Select
    Resume fMakeBackup_End
End Function

Private Function fCurrentDBDir() As String
Dim strDBPath As String
Dim strDBFile As String
    strDBPath = CurrentDb.Name
    strDBFile = Dir(strDBPath)
    fCurrentDBDir = Left(strDBPath, InStr(strDBPath, strDBFile) - 1)
End Function

Function fDBExclusive() As Integer
Dim db As Database
Dim hFile As Integer
    hFile = FreeFile
    Set db = CurrentDb
    On Error Resume Next
    Open db.Name For Binary Access Read Write Shared As hFile
    Select Case Err
        Case 0
            fDBExclusive = False
        Case 70
            fDBExclusive = True
        Case Else
            fDBExclusive = Err
    End Select
    Close hFile
    On Error GoTo 0
End Function
Avatar billede Slettet bruger
22. juni 2008 - 17:38 #3
Du smider selvfølgelig koden i et modul, som kan hedde hvad det sku' være!~)
Avatar billede jind Nybegynder
22. juni 2008 - 19:05 #4
Tak for hurtigt svar!

Duer denne kode også hvis den kaldes fra en frontend - og skal lave backup af et par backends?

- og hvor sætter jeg så stien til backends ind?
Avatar billede jind Nybegynder
22. juni 2008 - 19:12 #5
Terry: min kode ser således ud:
  Set CN = CurrentProject.Connection
 
  Set RS = New Recordset
        strSQL1 = "SELECT * FROM DB_link"
        RS.Open strSQL1, CN, adOpenKeyset, adLockOptimistic, adCmdText
   

  RS.MoveFirst
    db_link = RS!dblink
    RS.Find "DBlinkID = 2"
    Backuplink = RS!dblink
    RS.MoveFirst
    If nobackup = 0 Then
        FileCopy db_link & "dat.mdb", Backuplink & "data_" & Format(Now, "yyyymmdd") & Format(Time, "hhmm") & ".mdb"
        FileCopy db_link & "doku.mdb", Backuplink & "dok_" & Format(date, "yyyymmdd") & ".mdb"
        FileCopy db_link & "subs.mdb", Backuplink & "sub_" & Format(Now, "yyyymmdd") & Format(Time, "hhmm") & ".mdb"
    End If
    RS.Close
    Set RS = Nothing
Avatar billede Slettet bruger
22. juni 2008 - 19:49 #6
Prøv at lave denne del om:

Function fMakeBackup(strSaveFile As String) As Boolean
Dim strMsg As String
Dim tshFileOp As SHFILEOPSTRUCT
Dim lngRet As Long
'      Dim strSaveFile As String
Dim lngFlags As Long
Const cERR_USER_CANCEL = vbObjectError + 1
Const cERR_DB_EXCLUSIVE = vbObjectError + 2
    On Local Error GoTo fMakeBackup_Err

    If fDBExclusive = True Then Err.Raise cERR_DB_EXCLUSIVE
 
    strMsg = "Er du sikker på at du vil lave et kopi af databasen?"
    If MsgBox(strMsg, vbQuestion + vbYesNo) = vbNo Then _
            Err.Raise cERR_USER_CANCEL
         
    'lngFlags = FOF_SIMPLEPROGRESS Or _
    '                        FOF_FILESONLY Or _
    '                        FOF_RENAMEONCOLLISION
    'strSaveFile = CurrentDb.Name
 
    lngFlags = FOF_SIMPLEPROGRESS Or _
                            FOF_FILESONLY
    '        strSaveFile = "c:\backup\DinDatabase.mdb"

og så kald flere gange:

call fmakebackup("c:\backup\DinDatabase.mdb")
call fmakebackup("c:\backup\DinAndenDatabase.mdb")

osv.. jeg har ikke testet!~)
Avatar billede Slettet bruger
22. juni 2008 - 19:50 #7
forresten så ang. din kode, så bruger du filecopy og den virker ikke på en fil, som er i brug...
Avatar billede Slettet bruger
22. juni 2008 - 20:32 #8
Nej, det er noget sludder jeg bilder dig ind.... Koden laver backup af den db, som den kaldes fra, så den sidste tilrettelse vil bare gemme den aktuelle db flere steder!~)

Det må du undskylde, jeg har lidt travlt!~)

Det betyder også, at jeg ikke lige kan finde rette koden til nu, men jeg tjekker nok ind i morgen. Så hvis du ikke har en løsning inden da, så skal jeg nok prøve igen, jeg mener også, at jeg har lavet et anden løsning på et tidspunkt..  Nåeh.. til i morgen... held og lykke!~)
Avatar billede Slettet bruger
23. juni 2008 - 07:53 #9
Du kan forresten bruge shell, det er noget mere simpel:

Private Sub KopiereBackend_Click()
Dim a
a = Shell("COMMAND.COM /C copy C:\Users\spg\Desktop\db1.mdb c:\Users\spg\Desktop\db1_copy.mdb")
End Sub
Avatar billede jind Nybegynder
23. juni 2008 - 09:35 #10
Hej SPG,
Ja, det ser jo unægteligt lidt pænere ud, men jeg har lidt problemer med den. Min kode ser således ud:

Public Sub Backup()
    Set RS = New Recordset
        strSQL1 = "SELECT * FROM DB_link"
        RS.Open strSQL1, CN, adOpenKeyset, adLockOptimistic, adCmdText
    RS.MoveFirst
    db_link = RS!dblink
    RS.Find "DBlinkID = 2"
    Backuplink = RS!dblink

data = db_link & "data.mdb"
data_copy = Backuplink & "data_" & Format(Now, "yyyymmdd") & Format(Time, "hhmm") & ".mdb"
a = Shell("COMMAND.COM /C copy data data_copy")
End sub

Der kommer ingen fejl meddelelser, men der kommer heller ingen nye filer i min backupmappe.
Er der noget jeg har misset? Kan det være fordi der er mellemrum i navnet på en af mine mapper? Fx "documents and settings" - eller kan man ikke hente variable ind til shell komandoen?
Avatar billede Slettet bruger
23. juni 2008 - 09:55 #11
Har du dim data as string og dim data_copy as string i din kode?~)

Prøv evt. at køre en debug i vba'en..
Avatar billede Slettet bruger
23. juni 2008 - 09:57 #12
ellers kan det også være noget i denne retning:

a = Shell("COMMAND.COM /C copy " & data & " " & data_copy)
Avatar billede jind Nybegynder
23. juni 2008 - 11:25 #13
Hej Spg,
Jeg har dim variablerne.
Dit sidste ex virker ikke - jeg har prøvet et utal af variationer over "". Men åbentbart ikke den rigtige.
Avatar billede Slettet bruger
23. juni 2008 - 11:39 #14
Avatar billede hugopedersen Nybegynder
24. juni 2008 - 15:25 #15
Inden du bruger sidste forslag, så læs lige advarslerne og beslut om du tør risikere en deffekt database.
Det eneste sikre er at checke om man kan få exclusiv adgang til filen før man kopierer.
Jeg har været nede af den vej og har haft en del databaser med fejl efter forsøg på at kopiere filen mens den er åben.
Avatar billede terry Ekspert
24. juni 2008 - 21:16 #16
Avatar billede jind Nybegynder
24. juni 2008 - 22:02 #17
Hej Igen,
Ja, det lader jo til at der ikke er nogle nemme løsninger. Jeg hælder til spg's svar på trods af hugo pedersens advarsler - og blot sørge for at der ofte bliver taget backup- som jeg forstod teksten på Microsoft side, var der tale om fejl i backuppen - og ikke i den kørende DB.
Terry - det ser ud til at være en lidt speciel løsning? Opdateres den til tekst fil - og så kan man he nte den bagefter? Lyder svært. :o)

Jeg satser på at få afprøvet nogle flere variationer over "" eller """ i spg's forslag.
Vender tilbage når det lykkes.

Og tak - jeg kan ikke andet end blive imponeret over den altid gode hjælp man får herinde.
Avatar billede hugopedersen Nybegynder
25. juni 2008 - 07:49 #18
Terry's forslag er et godt alternativ til en rigtig backup, blot skal du lige være obs på at skifter du til Access 2007 kan der opstå problemer med at exportere tabeller til textfiler - brug XML i stedet.  Jeg bruger selv metoden til at lave backups mens jeg udvikler. Så har jeg lavet en mulighed i mine apps for at genindlæse fra de enkelte textfiler. Så er det nemmere at gå et skridt tilbage.
Avatar billede terry Ekspert
22. august 2008 - 17:10 #19
Hows it going, have you found a solution yet?
Avatar billede jind Nybegynder
22. august 2008 - 18:24 #20
Hej Terry,
Jeg er klar over det - sorry.
Men nej, jeg gik lidt i stå - men vender tilbage senere i septemeber, da det er en koden skal i en løsning der praktisk taget er solgt.

Vh
Jind
Avatar billede terry Ekspert
22. august 2008 - 18:45 #21
OK.
Avatar billede Slettet bruger
22. august 2008 - 22:24 #22
husk at db_link i dit eksempel skal slutte på \

du kan evt. lige prøve msgbox data og msgbox data_copy for at sikre at det ser fornuftigt ud!~)
Avatar billede jind Nybegynder
13. november 2008 - 10:12 #23
I får lige dele point. Jeg har ikke fundet den rette løsning endnu - men tænker at hårdkode en backup som simpelt hen opretter en ny database og nye tabeller og fylder relevante data i med do until RS.eof.
Jeg takker for jeres hjælp og vender måske tilbage når jeg har siddet lidt mere med det.
Avatar billede terry Ekspert
13. november 2008 - 10:49 #24
tak
Avatar billede Slettet bruger
13. november 2008 - 22:24 #25
!~)
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