Protection du code & Compilation ?
Un classeur excel ne peut être compilé !! Il y a alors différentes protections possibles :
protéger le classeur à travers l'option offerte sous Visual basic editor créer des activex en vb ou c++ mais il faut penser à lesdistribuer et enregistrer sur chaque posteutiliser une macro complémentaire
XL97 : How to Create an Add-in File in Microsoft Excel 97" http://support.microsoft.com/support/kb/articles/Q156/9/42.ASP
HOWTO: Build an Add-in (XLL) for Excel Using Visual C++ http://support.microsoft.com/support/kb/articles/Q178/4/74.ASP
en outre, je crois que vous pouvez créer des DLL avec Excel 2000!??????? => COM Add-Ins (Excel 2000 Developer Edition only)
un tutorial à ce sujet : http://msdn.microsoft.com/library/periodic/period99/11vbpj/ss1199.htm
créer des macros qui efface le code ou autre :
Auto-destruction d'un classeur (limitation) : news
Autre méthode de protection (contrôle de la date) : news1, news2
Nettoyage & Optimisation du code VBA
Comment réduire la taille de son classeur :
!!!! Nettoyer le code VBA : la
macro "Code Cleaner", conçu par Rob Bovey, va réduire
considérablement la taille de votre classeur
Voici d'autres infos dessus
!!!! Optimiser le code VBA : il faut simplifier au maximum vos instructions
et programmer avec les instructions adéquates
* par exemple, vous pouvez éviter que l'encadrement de cellules
prennent du temps et de la place en remplaçant les lignes générées
par l'enregistreur par de courtes instructions : voir xl_format.htm.
* sachez qu'il n'est pas forcément nécessaire de sélectionner
ou activer un objet, cela a même tendance à ralentir l'exécution
du code.
Ainsi vous pouvez écrire worksheets("Sheet1").range("A1").Font.Bold
= True à la place des trois lignes suivantes :
Worksheets("Sheet1").Activate
range("A1").Select
Selection.Font.Bold = True
* NE FORMATER PAS LES FEUILLES ENTIERES mais seulement les zones de cellules
concernées. Regarder notamment les instructions suivantes : activesheet.usedrange.select
et activesheet.currentregion.select [usedrange n'est pas top non plus en
fait]. Sur le principe que j'énonce plus haut, vous pouvez écrire
: range("A1").currentregion.interior.colorindex=39
* regarder les pages sur la programmation de Laurent : http://longre.free.fr/
* regarder les pages sur l'optimisation du code de Chip : http://www.cpearson.com/excel/optimize.htm
* regarder les pages sur l'optimisation du code de Mc Ritchie : Slow Response,
Speeding up Excel, Enhancing Performance http://www.geocities.com/davemcritchie/excel/slowresp.htm
* l'instruction Application.ScreenUpdating = False est conseillé, si vous ne l'utilisez pas à l'heure actuelle, vous verrez une sacrée différence dans les fichiers où les sélections et les mises en forme sont nombreuses. Pour certains besoins, il faut rétablir la mise à jour : Application.ScreenUpdating = True, entre autres pour utiliser un inputbox de type 8 (qui permet de sélectionner une plage de cellules).
* Si vous avez beaucoup de calculs, vous pouvez désactiver le recalcul
le temps de la macro
Application.Calculation = xlCalculationManual 'in XL97 & up
.. . your code here ...
Application.Calculation = xlCalculationAutomatic 'in XL97 & up
Equivalent VBA de Annuler/Répéter : application.undo & redo Définir des procédures de répétition et d'annulation
application.onrepeat "Répète la procédure
VB", "Classeur1.xls!Ma_Sub_répétée"
application.onundo "Annule la procédure VB", "Classeur1.xls!Ma_Sub_annulée"
!! Si une procédure n'utilise pas la méthode OnUndo, la commande
Undo est désactivée
Annuler une macro : Page "Undoing a VBA subroutine" sur
le site de John Walkenbach Désactiver autofill &
drag &
drop en même temps
: application.celldraganddrop = false Désactiver le control break et le réactiver : application.EnableCancelKey
= xlDisabled & application.EnableCancelKey = xlInterrupt Désactiver les procédures évènementielles
(ex : selection_change, sheet_activate, ...)
Private sub CommandButton1_Click() 'à mettre dans un bouton issu de la barre d'outils "Commande"
application.enableevents = not application.enableevents
CommandButton1.caption = application.enableevents 'affiche le statut dans le texte du bouton
end sub
Lister les procédures
Lister les procédures et/ou fonctions personnalisées :
news
Lister les procédures XL4 : news
Listing All Modules In A Workbook (from Chip Pearson)
Sub ListModules()
Dim VBComp As VBComponent
Dim Msg As StringFor Each VBComp In thisworkbook.VBProject.VBComponents
Msg = Msg & VBComp.Name & " Type: " & CompTypeToName(VBComp) & Chr(13)
Next VBComp
MsgBox MsgEnd Sub
Function CompTypeToName(VBComp As VBComponent) As String
Select Case VBComp.Type
Case vbext_ct_ActiveXDesigner
CompTypeToName = "ActiveX Designer"
Case vbext_ct_ClassModule
CompTypeToName = "Class Module"
Case vbext_ct_Document
CompTypeToName = "Document"
Case vbext_ct_MSForm
CompTypeToName = "MS Form"
Case vbext_ct_StdModule
CompTypeToName = "Standard Module"
Case Else
End SelectEnd Function
Listing All Procedures In A Module
Sub ListProcedures()
Dim VBCodeMod As CodeModule
Dim StartLine As Long
Dim Msg As String
Dim ProcName As StringSet VBCodeMod = thisworkbook.VBProject.VBComponents("SaveModule").CodeModule
With VBCodeMod
StartLine = .CountOfDeclarationLines + 1
Do Until StartLine > = .CountOfLines
Msg = Msg & .ProcOfLine(StartLine, vbext_pk_Proc) & Chr(13)
StartLine = StartLine + _
.ProcCountLines(.ProcOfLine(StartLine, _
vbext_pk_Proc), vbext_pk_Proc)
Loop
End With
MsgBox MsgEnd Sub
Copier une procéduresub NewWorkbook() '(XL97)
thisworkbook.VBProject.VBComponents("Module1").Export "Test.bas"
Set wkb = workbooks.add
wkb.VBProject.VBComponents.Import("Test.bas").name = "Module1"
kill "Test.bas"
end sub
Sub Exporte()
dim dobj As New DataObject, Texte As String
with thisworkbook.VBProject.VBComponents("Module1").CodeModule
Texte = .Lines(.ProcBodyLine("Rien", vbext_pk_Proc), _
.ProcCountLines("Rien", vbext_pk_Proc) - 1)
end with
' Ici, la variable Texte contient le texte de la fonction
' Copie de la variable Texte dans le presse-papiers
dobj.SetText Texte
dobj.PutInClipboard
' Recopie du contenu du presse-papiers dans une feuille de calcul
sheets.Add.Paste
end Sub
Insérer un fichier dans un module
Application.dialogs(xlDialogVbaInsertFile).show arg1:="c:\windows\bureau\Nouveau document texte.txt"
Suppression de code
Supprimer un module
Le code ci-dessous permet de supprimer la procédure "asupprimer" contenu dans le module "thisworkbook (code du classeur)
sub supprimer_module()
dim LineStart As long
dim Linecount As long
with thisworkbook.VBProject.VBComponents("thisworkbook").CodeModule
LineStart = .ProcStartLine("asupprimer", vbext_pk_Proc)
Linecount = .ProccountLines("asupprimer", vbext_pk_Proc)
.deleteLines LineStart, Linecount
end with
end sub
Supprimer la procédure "deleteMe" du module "Module1"
sub supprimer_procédure
dim LineStart As long
dim Linecount As long
with thisworkbook.VBProject.VBComponents("Module1").CodeModule
LineStart = .ProcStartLine("deleteMe", vbext_pk_Proc)
Linecount = .ProccountLines("deleteMe", vbext_pk_Proc)
.deleteLines LineStart, Linecount
end with
end sub
Supprimer la macro et son bouton : news par L.L
Enlever tout le code VBA d'un classeur
'permet d'enlever tout code : les modules, les classes de modules, les userforms, des feuilles, les macrosXL4, ....
'to remove all code : Regular module, Class modules, Userforms, Code in sheet and workbook modules, Excel 4 macro sheets, ....
sub RemoveAllCode()
'XL2K:
'dim VBComp As VBComponent, AllComp As VBComponents, ThisProj As VBProject
'XL97 & XL2K:
dim VBComp As Object, AllComp As Object, ThisProj As Object
dim ThisRef As Reference, WS As Worksheet, DLG As dialogsheet
if activeworkbook.name < > thisworkbook.name thenSet ThisProj = activeworkbook.VBProject
Set AllComp = ThisProj.VBComponents
for each VBComp In AllComp
with VBComp
select Case .type
Case vbext_ct_StdModule, vbext_ct_ClassModule, vbext_ct_MSform
AllComp.Remove VBComp
Case vbext_ct_document
.CodeModule.deleteLines 1, .CodeModule.countOfLines
end select
end with
next
for each ThisRef In ThisProj.References
if Not ThisRef.BuiltIn then ThisProj.References.Remove ThisRef
nextend if
application.DisplayAlerts = false
for each WS In Excel4Macrosheets
WS.delete
next
for each DLG In dialogsheets
DLG.delete
next
end sub
Autres actions sur le code & les modules
Masquer les Modules
Etant gêné par le fait que tous mes modules soient ouverts à l'ouverture de VBA, j'ai cherché une macro, L. L. m'en a fourni une, seul le module "Module1" n'est pas caché
sub Masquer_Feuilles_de_code
dim VBC As VBComponent 'si vous avez des problèmes, enlevez cette ligne pour voir
for each VBC In thisworkbook.VBProject.VBComponents
with VBC.CodeModule.CodePane.Window
if VBC.name < > "Module1" And .Visible then _
VBC.CodeModule.CodePane.Window.Visible = false
end with
next VBC
end sub
Compter une chaîne de caractères, comme "end sub"
sub compter()
dim k As Integer, j As Integer
dim z As long
dim NomProjet As String
searchstring = "end sub"
NomProjet = "import"
cptsearchstring = 0
nbproc = application.VBE.VBProjects("import").VBComponents.count
for j = 1 to nbproc
z = 1
for k = 1 to application.VBE.VBProjects("import").VBComponents(j).CodeModule.countOfLines - 1
if application.VBE.VBProjects("import").VBComponents(j).CodeModule.find(searchstring, z, 1, z + 1, 1, false, false) then
cptsearchstring = cptsearchstring + 1
end if
z = z + 1
next k
next j
msgbox ("Nombre d'occurences de " & Chr(34) & searchstring & Chr(34) & "dans le projet " & Chr(34) & NomProjet & Chr(34) & " : " & Chr(13) & cptsearchstring)
end sub
Remplacer une chaîne de caractères
sub remplacer_chaine_ds_code2()
' ceci est un test ahem,coucou,ahem
dim z As long, chaineLigne As String, j As Integer, NomProjet As String
ShString = "ahem"
NewString = "ughhhh"
NomProjet = "import"
for j = 1 to application.VBE.VBProjects(NomProjet).VBComponents.count
z = 1
for k = 1 to application.VBE.VBProjects(NomProjet).VBComponents(j).CodeModule.countOfLines - 1
if application.VBE.VBProjects(NomProjet).VBComponents(j).CodeModule.find(ShString, z, 1, z + 1, 1, false, false) then
chaineLigne = application.VBE.VBProjects(NomProjet).VBComponents(j).CodeModule.Lines(z, 1)
chaineLigne = application.Worksheetfunction.substitute(chaineLigne, ShString, NewString)
application.VBE.VBProjects(NomProjet).VBComponents(j).CodeModule.ReplaceLine Line:=z, String:=chaineLigne
end if
z = z + 1
next
next
' ceci est un autre test ahem,ahem,ahem
end sub
Remplacer une ligne : news