vbamania.pl
login:
hasło:
 
  *Rejestracja *Zapomniane hasło
 Dziś jest środa, 01 maja 2024 roku.
Ustaw jako stronę startową Ulubione Napisz
PowrótPowrót do serwisu  RegulaminRegulamin rssRSS

  tytuł wątku:
Wątki dyskusji

Optymalizacja pamięci


otwartyotwarty rozpoczął: _Z_ postów: 8



napisał: jottad
postów: 118


umieszczony:
3 października 2007
08:33

  
Jeszcze jeden link, wprawdzie traktujący o pobieraniu danych z Excela, ale cokolwiek powiązany z tym problemem:
http://support.microsoft.com/kb/319998
napisał: jalamas
postów: 316


umieszczony:
3 października 2007
00:24

edytowany:
3 października 2007
00:44

  
Cytat:
Wprawdzie za każdym wywołaniem formularza przyrasta
mnie nic nie przyrasta, pokaż swój cały kod.
Private Sub CommandButton1_Click()
    Dim i As Long
    Dim j As Long
    For i = 1 To 2000
        frmAdo2LisString.Show
        For j = 1 To 1000
        Next
        Unload frmAdo2LisString
    Next
End Sub


76 736
po 2000
76 636
po 2000
76 592
po 2000
76 592
po 2000
76 600
po 2000
76 592
po 2000
76 620
ile razy uruchamiasz te formę?
napisał: jottad
postów: 118


umieszczony:
2 października 2007
11:32

  
Cytat:
Wprawdzie za każdym wywołaniem formularza przyrasta zajęty przez Excela obszar pamięci, ale to raczej wina samego Excela niż kodu VBA.


Jesteś pewien? A może to przypadek opisany na stronie:
http://support.microsoft.com/kb/836863
?
napisał: _Z_
postów: 12


umieszczony:
29 września 2007
15:18

  
Dziekuję jalamas za całosciowe rozwiązanie i świetne referencje (MZTools pomaga).

Testowałem załączony przez Ciebie kod na kilku Excelach i działa bardzo zgrabnie. Wprawdzie za każdym wywołaniem formularza przyrasta zajęty przez Excela obszar pamięci, ale to raczej wina samego Excela niż kodu VBA. Co ciekawe o wiele więcej pamięci potrzebuje Excel 2003 niż Excel 2007.

Jeszcze raz dziękuję

- M
napisał: jalamas
postów: 316


umieszczony:
17 września 2007
00:25

  
Aplikacja dotyczy 1-dnego pliku mdb. Czyli można najprawdopodobniej użyć 1-dnego połączenia dla całego formularza

Cytat:
W formularzu pobieram dane do kontrolek, np do ListBox.
z modułu wykonuje funkcję "set blah = dajRS( oSQL )", która przekazuje Recordset, w funkcji następuje nawiązanie połączenia z mdb

Wobec tego, po co, dla 1-dnego formularza nawiązywać do tej samej mdb nowe połączenie przy wywołaniu tej procedury dla kolejnej kontrolki ? Przekaż połączenie jako parametr.

Cytat:
w formularzu przypisuję do kontrolek dane z blah

Jak? Ponieważ ja tego nie rozumiem, poproszę przykład, bo do ListBox niekoniecznie trzeba cały czas otwarty Recordset

Cytat:
Obsługuję błedy tylko w taki sposób, że testuję swój Add-in i ewentualne błędy usuwam.
To znaczy jak do tej pory w moim kodzie nie ma w ogóle On Error

To znaczy nie masz obsługi błędów.
Bo to co piszesz, to nie jest obsługa błędów, a jedynie testowanie aplikacji.
Nie na tym polega obsługa błędów, nie tylko dla ADO! Nie wyobrażam sobie takiej aplikacji, a zwłaszcza przy obsłudze bazy danych!
Ściągnij sobie MZTools, to Ci ułatwi sprawę.
Cytat:
Jak w przypadku zastosowania ADO z formularza nawiązać połączenie, wykonać zapytanie, oddać RS. Obecnie zamykanie połączenia i recordsetu czasem powoduje niemożność wybrania danych do Formularza lub arkusza.

To pytanie do mnie musisz uściślić, podać przykład tej "niemożności".

Przykład dość uproszczony, bo dla mnie w Twoim poście za mało szczegółów.
'----------------------------------------------------------
' Form Class module : frmAdo2LisString
' przypuscmy 2 kontrolki ListBox
' bez referencji do ADO !!!!
'----------------------------------------------------------
Option Explicit
Dim bIni As Boolean
Dim CnF As Object      ' OBJECT

Sub SQL2List(objList As MSForms.ListBox, ObjCnL As Object, ByVal sSql As String)
    On Error GoTo TableMdb2_Error
    Dim arrList
    Dim Rs As Object
    If SetRs(ObjCnR:=ObjCnL, ObjRs:=Rs, sRsSql:=sSql) = False Then Exit Sub
    With Rs
        ' juz mozna odlaczyc jesli tylko ogladamy
        Set .ActiveConnection = Nothing
        If (.BOF And .EOF) Then GoTo TableMdb2_Exit
        .MoveFirst: arrList = .GetRows(, adBookmarkFirst)
    End With
    With objList
        .MultiSelect = fmMultiSelectSingle: .ColumnCount = UBound(arrList, 2)
        .Column() = arrList: .ColumnWidths = "0;"    ' ukrywam sobie 1-sza kolumna z id_pozycja, np...
    End With

TableMdb2_Exit:
    On Error Resume Next
    ' co najmniej taka obsluga bledow jest konieczna poza tym dla listy mozna zamknac RS
    Call CloseRs(ObjRsC:=Rs)
    Exit Sub

TableMdb2_Error:
    ' komunikatu byc nie musi lecz dobra praktyka jest aby byl
    ' a info o tresci i procedurze w korej wystapil blad do plik logerror aplikacji
    ' tez powinno byc aby user moglo go Ci przeslac i abys wiedzial gdzie szukac
    MsgBox "Błąd : ( " & Err.Number & " ) " & Err.Description & vbCrLf & _
           "Procedura : " & "TableMdb2", vbExclamation
    Resume TableMdb2_Exit
End Sub

Private Sub lstAdo_1_Click()
    ' przykladowo
    Dim i As Long
    With ActiveControl
        If .ColumnCount > 0 Then
            For i = 0 To .ColumnCount - 1
                MsgBox .Column(i)
            Next
        End If
    End With
End Sub

Private Sub UserForm_Activate()
    If Not bIni Then
        If OpenConn(ObjCn:=CnF, sSciezkaBaza:=SciezkaBaza()) Then
            Call SQL2List(objList:=Me.lstAdo_1, _
                          ObjCnL:=CnF, _
                          sSql:="SELECT * FROM tbl_lista_1 ")
            'w tabeli powyzej sa pola np:id_pozycja, nazwa_pozycja, jakies_inne_pole
            Call SQL2List(objList:=Me.lstAdo_2, _
                          ObjCnL:=CnF, _
                          sSql:="SELECT * FROM tbl_lista_2 ")
            bIni = True
        End If
    End If
    ' jesli niepotrzebny a sadze ze nie nie znam szczegolow aplikacji
    Call CloseConn(ObjCnC:=CnF)
End Sub

Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
    Call CloseConn(ObjCnC:=CnF)
End Sub


'----------------------------------------------------------
' Standard Module : common_mod
' mozna uzyc w innych modulach czy klasach
'----------------------------------------------------------
Option Explicit

Public Const adUseClient = 3
Public Const adOpenForwardOnly = 0
Public Const adLockReadOnly = 1
Public Const adCmdText = 1
Public Const adStateOpen = 1
Public Const adBookmarkFirst = 1

Public Function OpenConn(ObjCn As Object, ByVal sSciezkaBaza As String) As Boolean
    On Error GoTo OpenConn_Error

    Dim strConn As String
    strConn = "Provider=Microsoft.Jet.OLEDB.4.0;" & _
              "Data Source=" & sSciezkaBaza & ";" & "Persist Security Info=False"
    Set ObjCn = CreateObject("ADODB.Connection")
    With ObjCn
        .CursorLocation = adUseClient: .Open strConn
    End With
    OpenConn = True

OpenConn_Exit:
    Exit Function

OpenConn_Error:
    Call CloseConn(ObjCnC:=ObjCn)
    OpenConn = False
    MsgBox "Błąd : ( " & Err.Number & " ) " & Err.Description & vbCrLf & _
           "Procedura : " & "OpenConn", vbExclamation
    Resume OpenConn_Exit
End Function

Public Function SetRs(ObjCnR As Object, ObjRs As Object, ByVal sRsSql As String) As Boolean
    On Error GoTo SetRs_Error
    Set ObjRs = CreateObject("ADODB.Recordset")
    ObjRs.Open sRsSql, ObjCnR, adOpenForwardOnly, adLockReadOnly, adCmdText
    SetRs = True
SetRs_Exit:
    Exit Function
    
SetRs_Error:
    Call CloseRs(ObjRsC:=ObjRs)
    MsgBox "Błąd : ( " & Err.Number & " ) " & Err.Description & vbCrLf & _
           "Procedura : " & "SetRs", vbExclamation
    Resume SetRs_Exit
End Function

Public Sub CloseRs(ObjRsC As Object)
    If Not ObjRsC Is Nothing Then
        With ObjRsC
            If .State = adStateOpen Then .Close
        End With
    End If
    Set ObjRsC = Nothing
End Sub

Public Sub CloseConn(ObjCnC As Object)
    If Not ObjCnC Is Nothing Then
        With ObjCnC
            If .State = adStateOpen Then .Close
        End With
    End If
    Set ObjCnC = Nothing
End Sub

napisał: _Z_
postów: 12


umieszczony:
16 września 2007
20:04

  
Witam,

na początek tło. Add-in wywołuje Formsy. W formularzu pobieram dane do kontrolek, np do ListBox. To wymaga od programu, by:
+ przypisać do oSQL konkretnego selecta
+ z modułu wykonuje funkcję "set blah = dajRS( oSQL )", która przekazuje Recordset, w funkcji następuje nawiązanie połączenia z mdb
+ w formularzu przypisuję do kontrolek dane z blah
+ set blah = nothing

Stosuję późne wiązanie.


Q: - rozmiar pliku mdb
A: 111 MB

Q: - czy rozmiar ten wzrasta po zamknięciu Twojej aplikacji
A: Nie. Wykonuję tylko zapytania.

Q: - czy mdb jest skompaktowana
A: Nie.

Q: - czy ma wyłączoną autokorektę nazw
A: Nie

Q: - czy po pobraniu danych w katalogu, gdzie znajduje się mdb widać plik ldb?
A: Raczej nie.

Q: - czy pracujesz na 1-dnym połączeniu, czy w każdej procedurze tworzysz nowe
A: niestety ale

Q: - czy obsługujesz błędy
A: Obsługuję błedy tylko w taki sposób, że testuję swój Add-in i ewentualne błędy usuwam.

Q: - czy na przykład wykorzystujesz: On Error Resume Next szczęśliwy, że nie ma komunikatu o błędach...
A: Staram się tego unikać. To znaczy jak do tej pory w moim kodzie nie ma wogóle On Error. Gdy w czasie testowania napotykam błąd to raczej go usuwam niż obchodzę. Jedyną sytuacją wykorzystania On Error było
gdy tylko On Error dawało możliwość przetwarzania warunkowego.

Q: - czy na bank zawsze zamykasz wszystkie Recordset i Connection przy wyjściu z procedury,
a także wówczas, gdy wystąpi błąd
A: Architektura formularza nie pozwala mi (albo nie umiem tego robić) bym zamykał wszystkie Recordset i Connection. To znaczy Recordset zamykam, ale nie wiem kiedy powinienem zamknąć i wyzerować Connection.

Q: - czy pamiętasz o tym, by zawsze każdej zmiennej Recordset i Connection itp. przypisać Nothing przy wyjściu z procedury, a także wówczas, gdy wystąpi błąd:
Set mój_obiekt= Nothing

Moje pytanie jest więc teraz takie. Jak w przypadku zastosowania ADO z formularza nawiązać połączenie, wykonać zapytanie, oddać RS. Obecnie zamykanie połączenia i recordsetu czasem powoduje niemożność wybrania danych do Formularza lub arkusza.

Pozdrawiam

- Marcin
napisał: jalamas
postów: 316


umieszczony:
16 września 2007
09:34

  
Trudno mi w ciemno orzekać o przyczynach, zadam wobec tego pytania:
- rozmiar pliku mdb
- czy rozmiar ten wzrasta po zamknięciu Twojej aplikacji
- czy mdb jest skompaktowana
- czy ma wyłączoną autokorektę nazw
- czy po pobraniu danych w katalogu, gdzie znajduje się mdb widać plik ldb?

W procedurach obsługi bazy danych
- czy pracujesz na 1-dnym połączeniu, czy w każdej procedurze tworzysz nowe
- czy obsługujesz błędy
- czy na przykład wykorzystujesz: On Error Resume Next
szczęśliwy, że nie ma komunikatu o błędach...
- czy na bank zawsze zamykasz wszystkie Recordset i Connection przy wyjściu z procedury,
a także wówczas, gdy wystąpi błąd
- czy pamiętasz o tym, by zawsze każdej zmiennej Recordset i Connection itp. przypisać Nothing przy wyjściu z procedury,
a także wówczas, gdy wystąpi błąd:
Set mój_obiekt= Nothing

Oraz przytocz tutaj taką napisaną przez Ciebie procedurę.
napisał: _Z_
postów: 12


umieszczony:
15 września 2007
18:59

  
Witam,

W moim add-in pobieram dane z Accessa (plik MDB) i wkładam do Excela. Stosuję późne wiązanie, kompilację, ale cały czas mam problem z zapotrzebowaniem na pamięć. W czasie pracy dodatku zapotrzebowanie na plik stron wzrasta z około 600MB do ponad 1,2 GB, co skutecznie może unieruchomić system (fizycznej pamięci mam 512MB).

Czy macie jakieś rady jak poradzić sobie z tym wyzwaniem?

Pzdr

- Marcin


<-wstecz  1  dalej->
wszystkich stron: 1


Sortuj posty: z