M-am confruntat de cateva ori cu urmatoarea situatie: reusesc sa deschid un fisier excel, dar Editorul VBA nu vrea sa se deschida. Excelul se blocheaza si nu mai poate fi oprit decat cu TaskManagerul de la procese.
De data asta am cautat cu Google-ul o rezolvare, si am aflat ca:
1) Excelul 2007 si 2010 e posibil sa nu aibe aceasta problema.
2) Acest lucru se intampla pentru ca in timpul lucrului la o aplicatie VBA, fisierul se incarca cu foarte mult junk, care la un moment dat poate sa dea erori si de acest gen.
3) O solutie pentru recuperarea fisierului, care la mine a mers, este disabilitarea macrourilor. Asta face ca sa poata fi deschis Editorul VBA pentru a exporta toate modulele de cod.
4) Exportarea tuturor modulelor de cod (cu stergerea lor), compilarea fisierului, reimportarea modulelor, si recompilarea fisierului, face ca acesta sa devina curat. Alte metode, nu atat de eficiente in ce priveste VBA-ul constau in filtrarea fisierului xls prin salvarea lui in alt format, dupa care salvarea lui din nou in format xls.
5) Sant si unele programe sau extensii ale Excelului care ar curata fisierul, dar nu stiu cat de bine ar face asta, sau daca sunt si pentru Excel 2003. Ba are si Office-ul 2003 un program Application Recovery pe care stiu ca l-am folosit odata si nu a avut nici un efect in legatura cu asta.
Atasez aici doua variante ale unui modul standard (nu pot fi postate decat fisiere care au anumite extensii, si de aceea am postat codul respectiv), care are doua proceduri utile pentru exportul, stergerea, si importul modulelor din Workbookul de care apartine.
Procedura de import merge foarte bine. Procedura de export si stergere nu am avut curaj sa o incerc, dar cel putin una dintre versiuni ar trebui sa mearga. Mai multi forumisti spuneau ca nu reusesc sa salveze decat un singur modul.
Click intr-o procedura care nu are parametri dintr-un modul standard, si cu F8 ea poate fi rulata pas cu pas (vezi si meniul Debug).
Pentru ca codul acestui modul sa functioneze trebuiesc facute doua lucruri:
1) O referinta la componenta "Microsoft Visual Basic for Applications Extensibility 5.3" in Editorul VBA (Tools > References).
2) Trebuie bifata in Excel optiunea "Trust access to Visual Basic Project" in fereastra Tools > Macro > Security... > Tabul Trusted Publishers (al 2-lea) - http://www.pcreview.co.uk/forums/thread-3797357.php
Poate fi programat si Editorul VBA nu numai programele Office
Fisierele exportate sunt fisiere text (chiar daca au alte extensii - .bas pentru modulele standard/basic), si pot fi create/vizualizate cu Notepad-ul.
Prima varianta
Cod: Selectaţi tot
Option Explicit
'Trebuie o referinta la componenta "Microsoft Visual Basic for Applications Extensibility 5.3"
'Trebuie sa fie bifata optiunea "Trust access to Visual Basic Project" in
'fereastra din Excel, Tools > Macro > Security... > Tabul Trusted Publishers.
'Optiunea este critica
'permite accesul la unele elemenet core,
'nu tine cont de nivelul de securitate pentru macrouri,
'si trebuie debifata imediat dupa terminarea operatiunii.
'Procedura de compactare:
'1) Se executa ModulesExportRemove. 2) Se compileaza ce ramane. 3) Se executa ModulesImport.
Private Sub ModulesExportRemove()
Dim VBCmps As VBComponents, VBCmp As VBComponent
Dim Pth As String, FNm As String, DtSfx As String
Pth = ThisWorkbook.Path & "\Modules Recoverings\"
DtSfx = " - " & Format(Date, "yyyy-mm-dd")
Set VBCmps = ThisWorkbook.VBProject.VBComponents
For Each VBCmp In VBCmps
If VBCmp.Type <> vbext_ct_Document And (VBCmp.Name <> "ModulesExImCompression") Then
FNm = VBCmp.Name
Select Case VBCmp.Type
Case vbext_ct_Document: FNm = "wst " & FNm & DtSfx & ".wst" '".cls" in mod normal
Case vbext_ct_ActiveXDesigner: FNm = "axd " & FNm & DtSfx & ".axd"
Case vbext_ct_MSForm: FNm = "frm " & FNm & DtSfx & ".frm"
Case vbext_ct_StdModule: FNm = "bas " & FNm & DtSfx & ".bas"
Case vbext_ct_ClassModule: FNm = "cls " & FNm & DtSfx & ".cls"
Case Else: Stop
End Select
VBCmp.Export Pth & FNm
VBCmps.Remove VBCmp
End If
Next
End Sub
Private Sub ModulesImport()
Dim Pth As String, FNm As String
Pth = ThisWorkbook.Path & "\Modules Recoverings\"
FNm = Dir(Pth)
Do While FNm <> ""
Select Case Right(FNm, 4)
Case ".axd", ".frm", ".bas", ".cls"
ThisWorkbook.VBProject.VBComponents.Import Pth & FNm
Case "wst" 'Worksheet care ar fi importat ca o clasa. In mod normal ar avea extensia .cls
End Select
FNm = Dir
Loop
End Sub
Cod: Selectaţi tot
Option Explicit
'Trebuie o referinta la componenta "Microsoft Visual Basic for Applications Extensibility 5.3"
'Trebuie sa fie bifata optiunea "Trust access to Visual Basic Project" in
'fereastra din Excel, Tools > Macro > Security... > Tabul Trusted Publishers.
'Optiunea este critica
'permite accesul la unele elemenet core,
'nu tine cont de nivelul de securitate pentru macrouri,
'si trebuie debifata imediat dupa terminarea operatiunii.
'Procedura de compactare:
'1) Se executa ModulesExportRemove. 2) Se compileaza ce ramane. 3) Se executa ModulesImport.
Private Sub ModulesExportRemove()
Dim VBCmps As VBComponents, VBCmp As VBComponent
Dim Pth As String, FNm As String, DtSfx As String
Dim Match As Boolean
Pth = ThisWorkbook.Path & "\Modules Recoverings\"
DtSfx = " - " & Format(Date, "yyyy-mm-dd")
Set VBCmps = ThisWorkbook.VBProject.VBComponents
Do While VBCmps.Count > 0
Match = False
For Each VBCmp In VBCmps
If (VBCmp.Type <> vbext_ct_Document) And _
(VBCmp.Name <> "ModulesExImCompression") Then Match = True: Exit For
Next
If Not Match Then Exit Do
FNm = VBCmp.Name
Select Case VBCmp.Type
Case vbext_ct_Document: FNm = "wst " & FNm & DtSfx & ".wst" '".cls" in mod normal
Case vbext_ct_ActiveXDesigner: FNm = "axd " & FNm & DtSfx & ".axd"
Case vbext_ct_MSForm: FNm = "frm " & FNm & DtSfx & ".frm"
Case vbext_ct_StdModule: FNm = "bas " & FNm & DtSfx & ".bas"
Case vbext_ct_ClassModule: FNm = "cls " & FNm & DtSfx & ".cls"
Case Else: Stop
End Select
VBCmp.Export Pth & FNm
VBCmps.Remove VBCmp
Loop
End Sub
Private Sub ModulesImport()
Dim Pth As String, FNm As String
Pth = ThisWorkbook.Path & "\Modules Recoverings\"
FNm = Dir(Pth)
Do While FNm <> ""
Select Case Right(FNm, 4)
Case ".axd", ".frm", ".bas", ".cls"
ThisWorkbook.VBProject.VBComponents.Import Pth & FNm
Case "wst" 'Worksheet care ar fi importat ca o clasa. In mod normal ar avea extensia .cls
End Select
FNm = Dir
Loop
End Sub
Toate cele bune!