Access 2016 Bijlagen opslaan op een andere locatie

Status
Niet open voor verdere reacties.

KPTPTT

Gebruiker
Lid geworden
2 mrt 2018
Berichten
321
Bijlagen die ik toevoeg aan een formulier, sla ik op op een andere locatie van de HD. De bijlagen worden volgens mij (en MS) niet in de database opgeslagen, althans dat is de bedoeling. Door het op deze manier opslaan van bijlagen, zoals foto's etc., zie ik de bestandgrootte van de database alsnog ongewenst behoorlijk toenemen.

Ik heb wat experimenten gedaan. Een Word bestand als bijlage aan het formulier toegevoegd op een andere locatie. Als ik dit bestand op de "andere locatie" verwijder en daarna de bijlage in het formulier open, wordt de bijlage alsnog getoond. De Word bijlage staat hierna, en is terug te vinden in een cache map van "App data" opgeslagen. Als ik deze verwijder en de bijlage weer open, staat hetzelfde bestand er weer. Hoe kan dit? Wordt de bijlage, ondanks de opslag op een andere locatie, ook opgeslagen in de database? Hoe kan ik voorkomen dat de bijlage niet in de database wordt opgeslagen maar op de andere locatie staat? MS is daar niet duidelijk over.

Dit is wat ik doe.
Tabel met een veld Bijlagen.
In het formulier staat een veld Bijlagen.
Open Bijlagen in het formulier.
Klik op Toevoegen en selecteer het op te slaan bestand. (Gaat hier iets fout? Wordt hiermee de bijlage alsnog in de database opgeslagen? Een andere manier om de bijlage te selecteren uit de bron-locatie zie ik niet)
Klik op Opslaan als en sla het bestand op een andere locatie op.
Klik op OK, klaar.
 
Dit is wat ik doe.
Tabel met een veld Bijlagen.
Daar ga je volgens mij al de teil in. Bijlagen nooit in een Bijlagen veld opslaan, dan staat het bestand namelijk echt wel in de database. En dat verklaart uiteraard ook de ongewenste groei. Altijd een tekstveld gebruiken, en de bijlage met FollowHyperlink openen.
 
Dank voor de reactie. Ik had van ms begrepen dat "Opslaan als" de oplossing is, maar nee. Vreemd dat er in de db de bijlagen alsnog wordt opgeslagen. Ik ga mij richten op je advies. Ik heb in dit forum al wat informatie gelezen en kijk of ik dit kan gebruiken.
 
Als je een Bijlagenveld gebruikt, wordt, wat je ook doet, de bijlage in de db gezet. Ik gebruik ze nooit, en gebruik alleen tekstverwijzingen naar de bestanden.
 
Hallo Octafish. Ik heb op het forum een voorbeeld db bestand van je gevonden (Voorbeeld Bijlagen module VBA garantie.zip) dat in de testversie precies doet wat ik zou willen, het opslaan van bijlagen met de functie FollowHyperlink. Echter wil ik meer (8x) bijlagen (Word, pdf, msg) opslaan in een voorgeselecteerde map Bijlagen.

Ik heb een tabel en heb daar de kolommen Bijlage1, Bijlage2, etc. (8x) en een kolom BijlagePad aan toegevoegd. In het formulier heb ik 8 bijbehorende tekstvelden Bijlage1, Bijlage2, etc. toegevoegd.
De VBA code van de voorbeeld db heb ik één op één overgenomen waarbij ik <me.Bijlage> heb vervangen door <me.Bijlage1> en de Padnaam heb aangepast met <\Bijlagen\>.
Waarschijnlijk door de warmte draait de code niet goed :confused:.

Situatie:
Tabel, velden Bijlage1,etc. zijn "leeg". Veld BijlagePad is "leeg".
Dubbelklik op veld Bijlage1 formulier geeft de melding: <Het bestand "" ontbreekt in de dossiermap, wil je het verwijderen uit de lijst?>
Er wordt geen bestandnaam (bestand "") in de pop up window vermeld (op zich klopt dit omdat er geen bestand is) maar je zou verwachten dat dan een bijlage wordt toegevoegd (volgens mij is bij de dubbelklik gegaan naar "Hell" ipv. BijlageToeveoegen"). Er wordt wel een map Bijlagen aangemaakt dus kennelijk gaat het programma toch Bekijk bijlage Voorbeeld Bijlagen module VBA garantie.zipnaar BijlageToevoegen. Dus enerzijds een error (Hell) en anderzijds een bijlagemap aanmaken? In de tabel is geen waarde bijlage1 en een BijlagePad geproduceerd. Verkenner wordt niet geopend (FileDialog) voor het toevoegen van de link.

De VBA code is complex en begrijp in grote lijnen (niet in detail) de code maar vraag mij dan ook af: "Wat kan de oorzaak zijn?" Graag je hulp svp..

Bijgaande bijlage je voorbeeld db "Voorbeeld Bijlagen module VBA garantie.zip" (Helaas kan ik de bron niet meer achterhalen)


Code:
Private Sub Bijlage1_DblClick(Cancel As Integer)
    On Error GoTo Hell
    If Me.Bijlage1 & "" = "" Then
        BijlageToevoegen
    Else
        DoCmd.SetWarnings False
        Application.FollowHyperlink Me.BijlagePad & Me.Bijlage1
        DoCmd.SetWarnings True
    End If
    Exit Sub

Hell:
    If MsgBox("Het bestand '" & LCase(Me.Bijlage1) & "' ontbreekt in de dossiermap; wil je het verwijderen uit de lijst?", vbYesNo) = vbYes Then
        Me.Bijlage1 = Null
    End If

End Sub

Private Sub BijlageToevoegen()
Dim sFile As String, sDoc As Variant
    
    If IsNull(Me.BijlagePad) Then Me.BijlagePad = fPadMaken(Application.CurrentProject.Path & "\Bijlagen\")
    
    sFile = BestandOpzoeken(Application.CurrentProject.Path & "\")
    If sFile = "Annuleren" Then Exit Sub
    If Not Dir(sFile) = "" Then
        If InStr(1, sFile, "\") = 0 Then Exit Sub
        sDoc = Split(sFile, "\")
        Me.Bijlage1 = sDoc(UBound(sDoc))
        On Error Resume Next
        FileCopy sFile, Me.BijlagePad & "\" & sDoc(UBound(sDoc))
        ''Me.Repaint
    End If
End Sub

Code:
Public Function fPadMaken(sFolder As String) As String
On Error GoTo ErrorHandler
Dim sF As String
    sF = GetPathOnly(sFolder)
    If Dir(sF, vbDirectory) = "" Then
      sF = fPadMaken(sF)
      MkDir sF
    End If
    fPadMaken = sFolder
    Exit Function
    
ErrorHandler:
    Exit Function
End Function

Public Function GetPathOnly(sPath As String) As String
    GetPathOnly = Left(sPath, InStrRev(sPath, "\", Len(sPath)) - 1)
End Function

Function BestandOpzoeken(Optional Pad As String) As String
Dim dlgPicker As Object
Dim sType() As String, sFile As String
Dim tmp As String, sPad As String
Dim bCheck As Boolean
Dim vrtSelectedItem As Variant

    On Error GoTo Hell
    If Pad = "" Then sPad = CreateObject("WScript.Shell").SpecialFolders("Mijn documenten") Else: sPad = Pad
    If Right(sPad, 1) <> "\" Then sPad = sPad & "\"
    Set dlgPicker = Application.FileDialog(3)
    With dlgPicker
        .Title = "Selecteer een bestand."                           'De titel voor het venster
        .InitialFileName = sPad                                     'Waar moet het venster beginnen?
        With .Filters
            .Clear
            .Add "Alles", "*.*", 1                                  'Geen Beperkingen op bestandstype"
            .Add "Microsoft Word", "*.doc; *.docx; *.docm", 2       'Beperk de bestandstypes tot .doc
            .Add "Microsoft Excel", "*.xls; *.xlsx; *.xlsm", 3      'Beperk de bestandstypes tot .xls
            .Add "Adobe Reader", "*.pdf", 4                         'Beperk de bestandstypes tot .pdf"
            .Add "Afbeeldingen", "*.jpg; *.jpeg; *.png", 5          'Beperk de bestandstypes tot afbeeldingen
        End With
        .FilterIndex = 1
        .AllowMultiSelect = False                   'Slechts ??n bestand kiezen toegestaan
        .InitialView = 1                            'Bepaal weergave
        If .Show = -1 Then                          'Bepaal of gebruiker op OK-knop heeft geklikt.
            sFile = .SelectedItems(1)               'String wordt gevuld met geselecteerde bestand
        Else
            MsgBox "Er is op <Annuleren> gedrukt..."
            BestandOpzoeken = "Annuleren"
            GoTo Hell
        End If
    End With
    BestandOpzoeken = sFile
    
Hell:
    Set dlgPicker = Nothing

End Function
 
Later we eens beginnen bij de basis: stap van die datarendundantie af. Het is altijd een heel slecht idee om in een tabel hetzelfde veld meerdere keren op te nemen; daarmee is je normalisatie gelijk bij het groot vuil gezet. Nooit doen dus! Wil je meerdere bijlagen kunnen opslaan (en wie wil dat nou niet?) maak dan een gekoppelde tabel aan en zet die met een doorlopend formulier op je hoofdformulier.

Dan blijft je db correct werken, heb je geen enkel probleem met het terugvinden van je bijlagen, zit er ook geen beperking aan de hoeveelheid velden (lees: bijlagen) die je kunt vullen/opslaan en hoef je ook nog eens niks te veranderen aan de code :). Bedenk eens hoeveel extra tijd het je gekost heeft om die 8 bijlagen velden te maken, en hoeveel tijd je jezelf had kunnen besparen ;).
 
Dank, een goed idee en zal als de bijlage test goed is verlopen, gaan uitzoeken hoe dit te realiseren. Ik ben aan het testen met voorlopig één bijlage en de VBA code (voor één bijlage) laat het tot nu afweten.

Ik merk dat er in mijn db een afwijking tov. het testprogramma Garantie is: Ik heb een VBA module gemaakt Module1 (geen klassemodule). Mogelijk draait deze module niet en wordt Verkenner daardoor niet geopend. Ik zie de modulenaam Module1 wel staan in de linker navigatielijst van de VBA module maar ik zie deze niet terug in het linker navigatievenster waar de tabellen en formulieren worden aangegeven. Draait de module dan wel? Waar zit het mankement? Wat kan ik doen? Is de VBA code wel goed aangepast door mij?
Ik zie ook geen mogelijkheden om de VBA code stap voor stap te debuggen om de oorzaak te achterhalen.
 
Ik zie ook geen mogelijkheden om de VBA code stap voor stap te debuggen om de oorzaak te achterhalen.
Die mogelijkheid is er natuurlijk wel, als je op een van de beginregels gaat staan en op <F9> drukt. Dan sta je in de Stap modus, en kun je met <F8> elke regel doorlopen.

Ik heb even gekeken, en het probleem is niet zozeer dat de code niet werkt, maar dat je het pad niet goed opslaat. Eigenlijk moet ik zeggen: je slaat het pad helemaal niet op. De door jou ingevoerde paden werken bij mij natuurlijk niet omdat ik die paden niet heb. Dus kan ik een bestandsnaam leegmaken op de aangegeven manier. Daarna zou de code een nieuw bestand moeten inladen, en dat doet hij an sich goed, maar dus alleen de bestandsnaam, niet het pad. Dat blijft staan. En dat werkt dus dan niet.
 
Dank je wel voor je antwoord. Ik begrijp niet helemaal je antwoord. Er wordt een map "Bijlagen" gemaakt in de Current directory. Dus kennelijk wordt het pad gevonden. Je schrijft: "Je slaat het pad helemaal niet op." Hoe kan dat? Waarom wel in de db "Voorbeeld Bijlagen module VBA garantie.zip"? Ik heb geen pad opgegeven, volgens mij wordt dit automatisch door de code bepaald.

Bij het debuggen heb ik het volgende verschil gevonden van mijn db tov. je db "Voorbeeld Bijlagen module VBA garantie.zip".

In "Public functie fPadMaken(sFolder as String)As String", regel "If Dir(sF,vbDirectory)="" Then" wordt nog in beiden db doorlopen echter bij mijn db is de volgende stap regel "End If, fPadMaken=sFolder, Exit function . De laatste drie regels End If, etc. wordt tweemaal doorlopen en de map Bijlagen wordt gemaakt waarna het programma stopt. Bij de "garantie.zip" db is de volgende stap regel "sF=fPadmaken(sF)", het programma loopt nu verder en vraagt om het bestand etc. zoals de bedoeling is.
De code is complex en kan dit niet overzien wat het verschil is en waarom. Het heeft te maken met jouw opmerking dat het pad niet wordt opgeslagen, denk ik.
 
Ik heb ook nog een tweede vraag voor dezelfde VBA code: Ik maak gebruik van een fe en een be db die beide op verschillende pc's via een netwerkverbinding draaien. De door de VBA code geproduceerde map Bijlagen wordt echter automatisch geplaatst in de directory waar de fe staat. Dit zou de directory van de be moeten zijn zodat deze ook door een andere gebruiker kan worden benaderd. Hoe zou ik de VBA code kunnen aanpassen zodat altijd een vast directory pad aan de zijde van de be voor de Bijlagen of in ieder geval automatisch het pad van de be wordt gebruikt?

Graag ook aandacht voor mijn vorige vraag #9, bedankt voor je hulp.
 
Wat de laatste vraag betreft: als je een code hebt met CurrentDB, dan krijg je dus altijd de gegevens van de Frontend, want dat is immers de current db. Niet de BE. Wil je altijd het pad van de BE gebruiken (is wel slim in dit geval) dan moet je dat pad dus als een Constante vastleggen in een module. In die situatie haal je dus altijd de waarde uit de constante, ongeacht waar de FE staat.

Je procedure kijkt één keer naar het veld Me.BijlagePad: als dat leeg is. Dan wordt het gevuld, en wordt de naam van het bestand uitgelezen met sDoc(UBound(sDoc)). Verander je daarna het document (gooi je bijvoorbeeld het veld leeg) dan kun je wel een nieuw bestand opzoeken, maar het pad blijft ingevuld staan. Kies je nu een andere map, dan klopt het dus niet meer, want in dat pad staat dat bestand niet.
 
Dank voor je bijdrage.
a) Tav. de laatste vraag met een vaste directory wil ik een deel van de regel: "fPadMaken(Application.CurrentProject.Path & "\Bijlagen\) aanpassen in: fPadMaken(\\JERRY\ D:/Documenten/Bijlagen db WO & "\Bijlagen") . Dit moet ik in de VBA module 2x uitvoeren. Ik twijfel of dit zo gaat werken (op zich al de richting van alle slashes, kloppen die?)). Hoe wel?

b) Met je tweede antwoord ben ik gaan puzzelen met wat je bedoeld. Het principe wat je beschrijft begrijp ik deels, maar . . . "Gooi je bijvoorbeeld het veld leeg", welk veld bedoel je? "Kies je een andere map", er wordt toch automatisch een map Bijlagen aangemaakt. Als ik een (Bijlage) veld in de tabel leeg, dan wordt toch bij een tweede dubbelklik het veld door de code weer gevuld? Van de db heb ik een kopie gemaakt en in een andere test directory gezet. Is daarmee de locatie van de map Bijlagen verplaatst. Wordt de eerste locatie van de map vast opgeslagen en gaat deze niet mee met de verplaatsing, is dat de clou? Je ziet ik kom er niet uit, ik kan de link niet leggen naar mijn situatie.

Hoe kan ik het oplossen? Wat moet ik met de code doen, aanpassen en waarmee? Waarom werk de garantie.zip database wel en de mijne met dezelfde code niet?
 
Je koppelt een UNC pad met een 'gewoon' pad. Dat zou ik zeker niet doen, want ik heb mijn grote twijfels of dat wel gaat werken. Elke vorm van string moet tussen dubbele quotes, dus alleen al op grond daarvan gaat je code niet werken.

Ik heb je situatie met meerdere velden aangepast, zodat je de code nu op meerdere losse bijlagevelden kunt toepassen. Dat vroeg een kleine aanpassing aan de procedure BijlageToevoegen omdat je daar nu de output nodig hebt om in een veld te kunnen zetten. Dus daar heb ik een functie van gemaakt. Je gebruikt hem dan zo:

Code:
Private Sub Bijlage1_DblClick(Cancel As Integer)
    On Error GoTo Hell
    If Me.Bijlage1 & "" = "" Then
        Me.Bijlage = funBijlageToevoegen
    Else
        DoCmd.SetWarnings False
        Application.FollowHyperlink Me.BijlagePad & Me.Bijlage1
        DoCmd.SetWarnings True
    End If
    Exit Sub

Hell:
    If MsgBox("Het bestand '" & LCase(Me.Bijlage1) & "' ontbreekt in de dossiermap; wil je het verwijderen uit de lijst?", vbYesNo) = vbYes Then
        Me.Bijlage1 = Null
    End If

End Sub

Code:
Private Sub Bijlage2_DblClick(Cancel As Integer)
    On Error GoTo Hell
    If Me.Bijlage2 & "" = "" Then
        Me.Bijlage2 = funBijlageToevoegen
    Else
        DoCmd.SetWarnings False
        Application.FollowHyperlink Me.BijlagePad & Me.Bijlage2
        DoCmd.SetWarnings True
    End If
    Exit Sub

Hell:
    If MsgBox("Het bestand '" & LCase(Me.Bijlage2) & "' ontbreekt in de dossiermap; wil je het verwijderen uit de lijst?", vbYesNo) = vbYes Then
        Me.Bijlage2 = Null
    End If

End Sub

En de functie wordt dan:
Code:
Private Function funBijlageToevoegen() As String
Dim sFile As String
    
    If IsNull(Me.BijlagePad) Then Me.BijlagePad = fPadMaken("\\JERRY\Documenten\Bijlagen db WO\Bijlagen\")
    sFile = BestandOpzoeken(Application.CurrentProject.Path & "\")
    If sFile = "Annuleren" Then Exit Function
    If Not Dir(sFile) = "" Then
        If InStr(1, sFile, "\") = 0 Then Exit Function
        funBijlageToevoegen = Split(sFile, "\")(UBound(Split(sFile, "\")))
        On Error Resume Next
        FileCopy sFile, Me.BijlagePad & "\" & sDoc(UBound(sDoc))
    End If
End Function
Kijk eens of je daar verder mee komt.
 
Dank voor je werk zo vroeg en blij met mensen die anderen helpen. Ik heb de code aangepast echter vraag ik mij af of de rest van de code de blokken Public Function fPadMaken (sFolder As String) As String en Public Function GetPathOnly . . . en Function BestandOpzoeken moet blijven bestaan of is alleen de code die je hebt opgegeven voldoende. Als ik deze blokken verwijder, dan krijg ik de foutmelding dat de function fPadMaken niet is gedefinieerd en dus heb ik de code laten staan.

Moet er achter de regel If Not Dir(sFile) = "" Then nog een uitgang bv. Exit Function komen te staan of niets en wordt er genest naar de volgende If?
Er was een compileerfout in het blok Private Function funBijlageToevoegen, er is geen End If gevonden.

Als ik dubbel klik op het Bijlage veld, dan wordt de oude fout weer getoond: <Het bestand "" ontbreekt in de dossiermap, wil je het verwijderen uit de lijst?>.

Mogelijk heb je nog een oplossing.
 
Als ik deze blokken verwijder, dan krijg ik de foutmelding dat de function fPadMaken niet is gedefinieerd en dus heb ik de code laten staan.
De functies zijn noodzakelijk om het geheel te laten werken; het zijn ook generieke functies die altijd werken en dus niet zijn gekoppeld aan een formulierveld. Functies die eigen op "As String" of "As Integer/Long" etc. leveren een output op die je kan hergebruiken. In jouw geval om één van de bijlagevelden te vullen. Je roept ze daarom ook aan met Me.Bijlage1 = funBijlageToevoegen.
De oude opdracht (BijlageToevoegen in de procedure Private Sub Bijlage_DblClick(Cancel As Integer)) leverde geen output maar produceerde die output in de procedure zelf: Me.Bijlage = sDoc(UBound(sDoc)). Daarom is een procedure minder handig, en al helemaal als je één functie wilt gebruiken om meerdere tekstvakken/velden te vullen. Dan móet je wel een functie gebruiken. Zoals je ziet, is de aanpassing in de code minimaal.
 
Ik laat de module1 dus intact en heb ik alleen de "dubbel klik" opdrachten aangepast. Echter krijg ik nog steeds de oude foutmelding: <Het bestand "" ontbreekt in de dossiermap, wil je het verwijderen uit de lijst?>. Het werkt dus nog niet.

Moet er achter de regel If Not Dir(sFile) = "" Then nog een uitgang bv. Exit Function komen te staan of niets en wordt er genest naar de volgende If?
Er was een compileerfout in het blok Private Function funBijlageToevoegen, er is geen End If gevonden.

Wat kan het zijn?
 
Ik heb de code uit een werkende db gekopieerd, en ik zie er ook niks vreemds aan. In het eerste blok zit wel een klein foutje, maar dat komt omdat ik jouw bijlagevelden niet heb, en de kopieën dus niet getest heb.
 
De tabelvelden Bijlagen en BijlagePad zijn leeg. De map Bijlagen wordt wel aangemaakt (dus dat vaste pad werkt) en is leeg. Het is dan logisch dat de melding gegevens wordt. As ik Ja heb geklikt wordt het bestand uit een leeg tabelveld Bijlage1 verwijderd. Dan zou je zeggen: "Alles is leeg" en kan dus een nieuw bestand worden geladen, maar nee.

Bij het debuggen zijn de volgende verschillen gevonden tussen de mijn db en de garantie.zip db.
In "Public functie fPadMaken(sFolder as String)As String", regel "If Dir(sF,vbDirectory)="" Then" wordt nog in beiden db doorlopen echter bij mijn db is de volgende stap regel "End If, fPadMaken=sFolder, Exit function . De laatste drie regels End If, etc. wordt tweemaal doorlopen en de map Bijlagen wordt gemaakt waarna het programma stopt. Bij de "garantie.zip" db is de volgende stap regel "sF=fPadmaken(sF)", het programma loopt nu verder en vraagt om het bestand etc. zoals de bedoeling is.
Ik kan dit niet overzien. Wat nu? Ik kan vanwege privacy redenen de db niet op dit internet forum plaatsen zodat je misschien er eens naar kan kijken. Weet je een mogelijkheid buiten het forum om om ondersteuning (mag tegen vergoeding, ook iemand anders).
 
In vervolg op mijn reactie #18. Ik heb inmiddels mijn db voor test "uitgekleed" maar wil hem nog niet op internet zetten. Zou je er svp. eens naar willen kijken wat er aan de hand is. Zo ja, heb je een emailadres of iets anders?
Ik zou het op prijs stellen.
 
Laatst bewerkt:
Je mag hem naar mij mailen.
 
Laatst bewerkt:
Status
Niet open voor verdere reacties.
Steun Ons

Nieuwste berichten

Terug
Bovenaan Onderaan