Neuigkeiten:

Wenn ihr euch für eine gute Antwort bedanken möchtet, im entsprechenden Posting einfach den Knopf "sag Danke" drücken!

Mobiles Hauptmenü

Mit Klassen Durch Inhaltsverzeichnis

Begonnen von silentwolf, November 20, 2016, 10:59:55

⏪ vorheriges - nächstes ⏩

silentwolf

Hallo nochmal,
Dim m_dbsExtern As Database
Dim m_rcsDaten As Recordset
Dim m_strRecordsetName As String
Dim m_strDatei As String
'

Public Property Let DateiName(strDateiname As String)
    m_strDatei = strDateiname
End Property

Public Property Get DateiName() As String
    DateiName = m_strDatei
End Property

Sub DateienImPfad()
   
    m_strDatei = Dir(PfadImport() & "*.accdb")
   
        Do Until m_strDatei = ""
           m_strDatei = Dir()
        Loop

End Sub

Sub OeffneExterneDB(strName As String)

    Set m_dbsExtern = OpenDatabase(CodeProject.Path & "\" & m_strDatei, , True)
   
End Sub

Sub OeffneExterneDaten(strName As String)
    Set m_dbsExtern = OpenDatabase(CodeProject.Path & "\DFG_NeuDatenTest.accdb", , True)
    m_strRecordsetName = strName
    Set m_rcsDaten = m_dbsExtern.OpenRecordset(m_strRecordsetName, dbOpenDynaset)
End Sub

Property Get RecordsetName() As String
    RecordsetName = m_strRecordsetName
End Property

Property Get AnzahlDatensaetze() As Long
    If m_rcsDaten Is Nothing Then
        AnzahlDatensaetze = -1
    Else
        With m_rcsDaten
            .MoveLast
            AnzahlDatensaetze = .RecordCount
            .MoveFirst
        End With
    End If
End Property

Private Sub Class_Terminate()
    Set m_rcsDaten = Nothing
End Sub


Das ist eine Klassenmodul und kein normales! Soweit kenne ich mich schon aus ;-)

hier sind die functions

Function PfadExport() As String
    PfadExport = PfadMitBackslash(CurrentProject.Path) & "Export\"
End Function

Function PfadImport() As String
'    PfadImport = PfadMitBackslash(CurrentProject.Path) & "Import\"
    PfadImport = PfadMitBackslash(CurrentProject.Path)
End Function


in einem Standart module

und hier ein Standartmodul um die Klasse zu iniatialisieren und zu verwenden
Sub TestDatensaetze()
    Dim clsDatenExtern As clsExterneDatenbanken
   
    Set clsDatenExtern = New clsExterneDatenbanken
    clsDatenExtern.OeffneExterneDaten "tblObjekt"
    Debug.Print clsDatenExtern.AnzahlDatensaetze & " in " & clsDatenExtern.RecordsetName
End Sub

Sub OeffneExterneDBImGleichenVerzeichnis()
    Dim clsDB As clsExterneDatenbanken
   
    Set clsDB = New clsExterneDatenbanken
    clsDB.OeffneExterneDB "DFG_Neu.accdb"
End Sub

Sub TesteDatenImInhaltsverzeichnis()
    Dim clsDir As clsExterneDatenbanken
   
    Set clsDir = New clsExterneDatenbanken
   
    clsDir.DateienImPfad

   
End Sub




silentwolf

Hallo nochmal,
erstmal vielen Dank das Ihr Euch hier so zahlreich meldet!

Also m_strName ist eine modul Öffentliche Variable im Klassenmodul die mit der Property Let gefüllt wird.

Die functions sind momentan noch in einem eigenen Modul aber natürlich als Public definiert um zugriff zu haben.
Dort wird der Pfad ausgegeben.

Also alles soweit vorhanden soweit ich es beurteilen kann ausser das ich nicht weis wie ich nun die Listbox in einem beliebigen formular mit diesem Wissen füllen kann.
Ich lese mir nochmal Eure Nachrichten genau durch und hoffe ich kann es dann erfolgreich erstellen :)


silentwolf

Zur Ergänzung einem formular habe ich folgenden Code..

Dieser Code funktioniert!

Dim m_strDatei As String
'


Private Sub Form_Current()
    Dim strDatei As String
   
    strDatei = Dir(PfadImport() & "*.accdb")
    Me!lstTabelDefs.RowSource = ""
   
    With Me.lstDateien
        .RowSource = ""
        Do Until strDatei = ""
           .RowSource = .RowSource & strDatei & ";"
           strDatei = Dir()
        Loop
    End With
   
    Me.lblDateien.Caption = Me.lstDateien.ListCount & " Access Dateien im Ordner " & CodeProject.Path

End Sub

Public Property Let DateiName(strDateiname As String)
    m_strDatei = strDateiname
End Property

Public Property Get DateiName() As String
    DateiName = m_strDatei
End Property

Private Sub lstDateien_AfterUpdate()
    Dim dbsExtern As Database
    Dim tdf As DAO.TableDef
   
    m_strDatei = Me!lstDateien.Column(0)

    Me!lstTabelDefs.RowSource = ""
    Me!lblTableDefs.Caption = m_strDatei
    On Error GoTo Fehler:
   
    Set dbsExtern = OpenDatabase(CodeProject.Path & "\" & m_strDatei, , True)

    For Each tdf In dbsExtern.TableDefs
        'Eliminate Sytem Tables and Tempory Tables
        If Left$(tdf.Name, 4) <> "MSys" And Left$(tdf.Name, 1) <> "~" Then
            lstTabelDefs.AddItem tdf.Name
        End If
    Next tdf
    Exit Sub
   
Fehler:
    MsgBox "Fehler Nr. " & Err.Number & ": " & Err.Description, vbCritical, "Öffnen der Datei" & p_cstrAppTitel

End Sub

Private Sub lstTabelDefs_AfterUpdate()
    Me.btnTabelDefs.Enabled = True
End Sub


Also hier ist genau das was ich erziehlen möchte. Nur wollte ich diesen Code verkürzen und in einem Klassenmodul das ich ja bereits gepostet habe ändern sodas ich mehr Flexibilität aus dem Code bekomme.
Also egal welches Verzeichnis oder welche Datei geöffnet wird und egal in welchen Formular ich das bewerkstellen möchte soll er Code funktionieren ..

Hoffe nun ein bisschen mehr Licht ins Dunkle bekommen habe :)




MzKlMu

Hallo,
warum genügt da nicht ein einfaches allgemeines Modul ?
Muss das ein Klassenmodul sein ?
Meiner Meinung nach gewinnst Du da doch nichts ?

Es mag sein, dass ich mich da irre und das Klassenmodul Vorteile bietet, die ich nicht erkenne.
Gruß Klaus

silentwolf

Hi Klaus,
natürlich bin ich auch kein Profi sonst würde ich nicht so dumm hier fragen ;-) Müssen wahrscheinlich nicht nur würde ich gewisse Dinge mehrfach ausführen dann wird es mit einem Klassenmodul schon etwas übersichtlicher und leichter...
Aber wie in meiner letzten Post das funktioniert bereits und ist schon recht gut..
Werde also vorerst mal dort weitermachen..


Josef P.

Hallo!

Ich verstehe den Zusammenhang der Klasse zum Öffnen einer Datenbank und dem Ausgeben eines Verzeichnisinhalts in eine Listbox nicht.

m_strDatei wird verwendet um den Namen einer Datebankdatei zu speichern. Warum wird dann die gleiche Variable für das Druchlaufen des Verzeichnisses verwendet?

Oder (erwähnte ich bereits):
Sub OeffneExterneDB(strName As String)
    Set m_dbsExtern = OpenDatabase(CodeProject.Path & "\" & m_strDatei, , True)
End Sub

Warum wird hier m_strDatei verwendet und der Parameter strName ignoriert?

mfg
Josef

silentwolf

Hallo,
momentan ist der Code etwas durcheinander da ich noch in der Testphase bin also habe ich noch ein Klassenmodul mit beiden Varianten.

Also ich Versuche zu meiner Uhrsprünglichen Post zu kommen.

Hier das Klassenmodule!!!! (Das ist das Klassenmodul und kein Normales oder Form Modul!)

Der Name dieser Klasse ist clsExterneDatenbanken

die Modulöffentliche Variablen im Klassenmodul

Dim m_dbsExtern As Database
Dim m_rcsDaten As Recordset
Dim m_strRecordsetName As String
Dim m_strDatei As String


Properties im Klassenmodul
Public Property Let DateiName(strDateiname As String)
    m_strDatei = strDateiname
End Property

Public Property Get DateiName() As String
    DateiName = m_strDatei
End Property


Hier mein bisheriger Code um eine Externe Datei zu öffnen auch im Klassenmodul!
Sub OeffneExterneDaten(strName As String)
    Set m_dbsExtern = OpenDatabase(CodeProject.Path & "\DFG_NeuDatenTest.accdb", , True)
    m_strRecordsetName = strName
    Set m_rcsDaten = m_dbsExtern.OpenRecordset(m_strRecordsetName, dbOpenDynaset)
End Sub



Im obrigen Code wird eine Externe DB geöffnet und mit einem Recordset gefüllt!

Was ich erreichen möchte!
Also in einem Normalen Module oder in einem Formmodule möchte ich in der Lage sein eine Listbox mit jedem beliebigen Verzeichnis zu füllen.

Zum Beispiel combobox mit verschiedenen Verzeichnissen diese Auswählen dann diese im Listenfeld anzeigen.

Listenfeld mit Verzeichnis auswählen dann in einem anderen Listenfeld die dazugehörigen Tabellen der Ausgewählten Datei anzeigen.

Ein Button wo ich die im ersten Listenfeld ausgewählten Datei angezeigt habe öffnen könnte.

Ein Button wo ich die dazugehörigen Tabellen der ausgewählten Datei in anzeigen oder öffnen kann.

Sub OeffneExterneDB(strName As String)

    Set m_dbsExtern = OpenDatabase(CodeProject.Path & "\" & m_strDatei, , True)
   
End Sub


Also ich möchte keine Verzeichnisse hard coden oder auch keine Datei deshalb mit Variablen zwischenspeichen und das ganze im Klassenmodul damit ich diese überall wo ich grad lustig bin verwenden kann.

Der nächste Schritt wäre halt mal das Listenfeld zu füllen wenn der Code im Klassenmodul steht :)


MzKlMu

Hallo,
Zitatund das ganze im Klassenmodul damit ich diese überall wo ich grad lustig bin verwenden kann.
aber genau das meine ich doch. Um den Code überall verwenden zu können bedarf es keines Klassenmoduls. Ein ganz normale allgemeines Modul tut es auch. Und da kann man den Wertelistenstring einer globalen Variablen zuweisen und diese Variable für die Zuweisung zum Listenfeld verwenden.

Wobei ich immer noch für eine Tabelle plädiere.
Gruß Klaus

silentwolf

Hallo Klaus,
na danke ja ich werde mal sehen wie ich es lösen werde...

Danke auf alle Fälle für Deine und Eure Tipps!

LG

ebs17

Was hat Deine Klasse, die sich mit Dateiöffnen per DAO beschäftigt, mit Verzeichnissen und deren Anzeige in Listenfeldern zu tun?

Eventuell sollte man sich erst einmal über Strategie und Abläufe klar werden, ehe man mit Codestücken um sich wirft. Der Bezug zwischen Deinen Darstellungen und dem Thementitel ist nicht wirklich nachvollziehbar.
Mit freundlichem Glück Auf!

Eberhard

Josef P.

#25
Hallo!

ZitatDer Name dieser Klasse ist clsExterneDatenbanken
[...]
Im obrigen Code wird eine Externe DB geöffnet und mit einem Recordset gefüllt!

ZitatWas ich erreichen möchte!
Also in einem Normalen Module oder in einem Formmodule möchte ich in der Lage sein eine Listbox mit jedem beliebigen Verzeichnis zu füllen.

Verstehe ich dich richtig: die Klasse dient dir nur als Vorlage. Du willst den Code zum Füllen der Listbox unabhängig von der gezeigten Klasse erstellen.

Mein Vorschlag:
Zerlege dein Vorhaben in mehrere überschaubare Aufgaben.
Ob du die Namen in einer Tabelle, Array, Recordet oder was auch immer weitergibst, ist für das Auslesen des Verzeichnisinhalts erstmal nicht relevant.

Was benötigst du?
* eine Auflistung der Dateien (mit Filter auf Dateierweiterung)
* einen Weg dieser Daten in die Listbox

=> Teilaufgaben:
1. Dateien im Verzeichnis ermitteln + Rückgabe als Array, Collection, ...
mögliches Interface:
Dateinamen = GetFilesFromFolder("D:\ein\Pfad", "*.accdb")

Anm.: eventuell ist Scripting.Folder ein Hilfe.

2. Daten in die Listbox bringen
mögliches Interface:
FillListbox ReferenzZurListbox, Dateinamen

Für die Umsetzung dieser 2 Hauptaufgaben können noch weitere Hilfsprozeduren benötigt werden. Das ergibt sich, wenn du den Code schreibst.
Tipp: In Prozeduren nicht mehrere Aufgaben umsetzten sondern diese in kleinere eigenständige Teilaufgaben gliedern und dafür wieder Prozeduren erstellen. Fallen in so einer Prozedur wieder mehrere Aufgaben an - weiter aufteilen usw. Das macht deinen Code später besser testbar, da du die Teilaufgaben getrennt überprüfen kannst. Bei einer guten Namenswahl wirst du beim Lesen des Codes auch schneller erkennen, was im Code abläuft.

Damit der Aufruf etwas einfacher wird, kannst du dann auch noch eine weitere Prozedur erstellen, die die zwei "Hauptprozeduren" verbindet.

Beispiel:
public sub FillFileNameListbox(byval lst as Listbox, byval FolderPath as string, byval FileNameFilter as String)
    FillListbox lst, GetFilesFromFolder(FolderPath, FileNameFilter)
end sub


Ob das nun in eine Klasse oder Standardmodul abgearbeitet wird, ist nicht so wichtig. Ich verwende gerne Klassen, da ich mir dann keine Prozedurnamen merken muss. ;)

mfg
Josef

silentwolf

Hallo ebs17,

also ich wollte eigentlich nicht mit Codestücken herumwerfen :) wollte eigentlich nur wie im ersten Post dargestellt wissen wie man über ein Klassenmodul ein Listenfeld füllen kann ohne diese hardcodiern zu müssen.

Ich möchte einfach eine Klasse die mir
1. Externe Dateien öffnet
2. Tabellen oder Abfragen dieser Datei anzeigt
3. Eine der Abfragen in eine andere Tabelle schreibt und mir die dazugehörigen Dateinamen anzeigt
4. Mir verschiedene Dateien bzw. Abfragen miteinander vergleicht
5. Die Klasse soll mir auch die Auswahl der anzuzeigenden Verzeichnisse auswählen lassen
6. Die Dateien filtern also entweder Access oder Excel Dateien

Hierzu dachte ich mir das ich es in einer Klasse auslagere und verschieden einsetzen kann je nach dem was ich eben mit einer Datei machen möchte.

Und nicht mehrere gleiche Prozeduren schreiben muss die das ein und das selbe erledigen sich aber nur in dem Verzeichnis, Dateinamen oder Tabellen bzw.Abfragen unterscheiden.

Meines Wissen ist dafür eine Klasse gedacht. Vielleicht liege ich falsch? So ein Profi bin ich natürlich nicht!!

Schöne Grüße






MzKlMu

Hallo,
Zitat2. Tabellen oder Abfragen dieser Datei anzeigt
Das kannst Du fast ohne Programmieren machen. Mit einer Abfrage kannst Du aus den Systemtabellen die Tabellen und Abfragen aus einer DB direkt ausgeben.

ZitatMir verschiedene Dateien bzw. Abfragen miteinander vergleicht
Dateien und Abfragen sind doch 2 ganz verschiedene Dinge. Eine Datenbankanwendung ist eine Datei und darin befinden sich Tabellen und Abfragen.

ZitatDie Klasse soll mir auch die Auswahl der anzuzeigenden Verzeichnisse auswählen lassen
Das ist schon wieder etwas anderes und hat mit Deinen anderen Anforderungen nichts zu tun.

ZitatDie Dateien filtern also entweder Access oder Excel Dateien
Aber eine Access Datei hat doch ganz andere Eigenschaften als eine Exceldatei.

Ich vermag hier nicht zu erkennen was Du da willst. Das sind doch völlig unterschiedliche Aufgaben, das kann doch nicht vermischt werden.
Gruß Klaus

silentwolf

Hallo Josef P.

danke auch Dir für Deine mail!
Ja das verstehe ich schon das ich es in kleinere Prozeduren aufgliedern soll das wäre ja mein Plan  ::)

Na ich schau mir das mal jetzt in Ruhe an mal sehen ob ich weiter komme :)

LG

silentwolf

Hallo Klaus,

danke für die Info.
Na ja ich glaube ich kann mich nicht gut genug ausdrücken.
Tut mir leid.. werde jetzt mal weiter machen vielleicht bekomme ich es ja trotzdem hin :)

Schönen Sonntag an alle!