FAQ MS-Access
FAQ MS-AccessConsultez toutes les FAQ
Nombre d'auteurs : 140, nombre de questions : 926, dernière mise à jour : 15 juin 2021
- Comment imprimer quatre états en choisissant l'imprimante une seule fois ?
- Comment dupliquer un enregistrement un nombre donné de fois ?
- Comment optimiser la vitesse d'affichage d'un état ?
- Comment insérer des lignes verticales ou créer un cadre pour l'ensemble de la page de mon état (sans dépendre de la taille de la section détail) ?
- Pourquoi dans mon état, Report_Activate ne se déclenche-t-il pas, donc aucune donnée ne s'affiche ?
- Comment choisir l'imprimante avec laquelle on va imprimer ?
- Comment visualiser mon état en mode paysage ?
- Comment dessiner dans un état (lignes ou autres) ?
- Comment masquer l'en-tête d'un état sur la première page de l'état ?
- Comment ouvrir une liste d'états à la suite ?
- Dans un état multicolonne, comment avoir un titre sur toute la largeur de la page ?
Mettre les quatre états en tant que sous-états d'un état vierge indépendant.
Vous voulez par exemple imprimer x fois un enregistrement (pour une étiquette ou autre).
Créez une table (tblCount) avec un seul champ ID (numérique)
et remplissez 1, 2, 3..... Nombre Maxi
Si votre requête est du genre :
Select
CLIENTS.NOM
From CLIENTS
Where CLIENTS.NOM
=
"TOTO"
;
Cette requête ne donne qu'un seul résultat.
Il faut alors la modifier pour utiliser la cardinalité :
Select
CLIENTS.NOM
From CLIENTS, TBLCOUNT
Where CLIENTS.NOM
=
"TOTO"
And
TblCount.Id
<=
5
;
et j'en ai alors cinq identiques.
Si vous voulez favoriser le rendement, créez une requête. Par exemple : qryxTonEtat.
Faites un état reposant sur cette requête.
Ensuite, en code, vous n'avez plus qu'à modifier le SQL de la requête.
Ainsi, cela évitera de créer des requêtes à la volée.
Vous aurez un état facilement modifiable puisqu'il aura une source.
Vous pourrez profiter pleinement de la technologie Rushmoore de recherche sur les index, ce qui n'est pas le cas pour le SQL dans le VBA. Et donc, les performances seront meilleures.
Dim
qdf as
QueryDef
set
qdf=
currentdb.querydefs
(
"qryxTonEtat"
)
qdf.SQL
=
"LeSQLquetuveux"
Il faut écrire :
Private
Sub
Report_Page
(
)
' Dessiner un bord de page autour de l'état.
Me.Line
(
0
, 0
)-(
Me.ScaleWidth
-
50
, Me.ScaleHeight
-
50
), , B
End
Sub
Lien : Complément
La propriété Fen indépendante doit être à Vrai, passez-la à Faux. Cela doit résoudre le problème.
Il faut passer par une API qui liste les imprimantes existantes, vous les collez dans une table temporaire et vous affichez tout cela dans un formulaire. L'utilisateur choisit l'imprimante et vous n'avez plus qu'à imprimer sur la ou les imprimantes sélectionnées.
Structure de la table des imprimantes tbPrtList :
- no_Prt, Entier ;
- tx_PrtNom, Texte 255 ;
- tx_PrtPort, Texte 255 ;
- tx_PrtDriver, Texte 255 ;
- st_Selection, Booléen.
SECTION MODULES DE FONCTIONNEMENT
Fonction permettant de charger les imprimantes dans la table :
Option
Compare Database
Option
Explicit
Function
fChargementImprimantes
(
)
' Fonction permettant de remplir une fois la table des imprimantes
' À lancer si nouvelle imprimante créée ou nouveau driver installé
' Cocher la case st_selection pour sélectionner les imprimantes
Dim
i As
Integer
Dim
itNbPrt As
Integer
Dim
rs As
Recordset
Static
atagDevices
(
) As
aht_tagDeviceRec
On
Error
GoTo
GestErr
Set
rs =
CurrentDb
(
).OpenRecordset
(
"tbPrtList"
, dbOpenDynaset)
' Suppression des enregistrements de la table
DoCmd.RunSQL
"DELETE * FROM tbPrtList"
' Détermine le nombre d'imprimantes en cours sur le poste
itNbPrt =
ahtGetPrinterList
(
atagDevices
(
))
' Ajoute les imprimantes dans la table pour les impressions
For
i =
1
To
itNbPrt
rs.AddNew
rs![No_Prt].Value
=
i
rs![tx_Prtnom].Value
=
atagDevices
(
i).drDeviceName
rs![tx_Prtport].Value
=
atagDevices
(
i).drPort
rs![tx_prtdriver].Value
=
atagDevices
(
i).drDriverName
rs.Update
Next
i
FinLoad
:
' Fermeture des objets
rs.Close
Set
rs =
Nothing
Exit
Function
' Gestion des erreurs
GestErr
:
MsgBox
"Erreur dans fChargementImprimantes : "
&
Error
&
" ("
&
Err
&
")"
Resume
FinLoad
End
Function
Fonction permettant d'imprimer l'état :
Function
fMultiImpression
(
stNomFichier As
String
)
' Impression d'états sur une ou plusieurs imprimantes
' Prérequis : l'état doit être en imprimante par défaut
' Paramètre : nom de l'état
On
Error
GoTo
GestErr
If
stNomFichier =
""
Then
Exit
Function
Dim
rs As
Recordset
Dim
dr As
aht_tagDeviceRec
Dim
stDvDefault As
String
' Unité de l'imprimante par défaut
Dim
stDrDefault As
String
' Driver de l'imprimante par défaut
Dim
stPrDefault As
String
' Port de l'imprimante par défaut
' Stockage des paramètres de l'imprimante par défaut actuelle
If
ahtGetDefaultPrinter
(
dr) Then
stDvDefault =
dr.drDeviceName
stDrDefault =
dr.drDriverName
stPrDefault =
dr.drPort
End
If
Set
rs =
CurrentDb
(
).OpenRecordset
(
"SELECT * FROM tbPrtList WHERE st_selection = true"
)
If
Not
rs.EOF
And
Not
rs.BOF
Then
While
Not
rs.EOF
' Chargement des paramètres de l'imprimante sélectionnée
dr.drDeviceName
=
rs.Fields
(
"[tx_PrtNom]"
)
dr.drDriverName
=
rs.Fields
(
"[tx_PrtDriver]"
)
dr.drPort
=
rs.Fields
(
"[tx_PrtPort]"
)
' L'imprimante devient imprimante par défaut
ahtSetDefaultPrinter dr
' Impression
DoCmd.OpenReport
stNomFichier, , acViewNormal
' Fermeture fichier
DoCmd.Close
acReport, stNomFichier
rs.MoveNext
Wend
End
If
RestoreDftPrt
:
' Fermeture des objets
rs.Close
Set
rs =
Nothing
' Restauration de l'imprimante par défaut
dr.drDeviceName
=
stDvDefault
dr.drDriverName
=
stDrDefault
dr.drPort
=
stPrDefault
ahtSetDefaultPrinter dr
Exit
Function
' Gestion des erreurs
GestErr
:
MsgBox
"Erreur dans fMultiImpression : "
&
Error
&
" ("
&
Err
&
")"
Resume
RestoreDftPrt
End
Function
SECTION API :
Const
MAX_SIZE =
255
Const
MAX_SECTION =
2048
Declare
Function
aht_apiGetPrivateProfileInt Lib
"kernel32"
Alias "GetPrivateProfileInt"
_
(
ByVal
strAppName As
String
, ByVal
strKeyName As
String
, ByVal
intDefault As
Integer
, _
ByVal
strFilename As
String
) As
Integer
Declare
Function
aht_apiGetPrivateProfileString Lib
"kernel32"
Alias "GetPrivateProfileStringA"
_
(
ByVal
strAppName As
String
, ByVal
strKeyName As
String
, ByVal
strDefault As
String
, _
ByVal
strReturned As
String
, ByVal
lngSize As
Long
, ByVal
strFilename As
String
) As
Long
Declare
Function
aht_apiGetProfileString Lib
"kernel32"
Alias "GetProfileStringA"
_
(
ByVal
strAppName As
String
, ByVal
strKeyName As
String
, ByVal
strDefault As
String
, _
ByVal
strReturned As
String
, ByVal
lngSize As
Long
) As
Long
Declare
Function
aht_apiGetProfileInt Lib
"kernel32"
Alias "GetProfileInt"
_
(
ByVal
strAppName As
String
, ByVal
strKeyName As
String
, ByVal
intDefault As
Integer
) As
Integer
Declare
Function
aht_apiGetProfileSection Lib
"kernel32"
Alias "GetProfileSectionA"
_
(
ByVal
lpAppName As
String
, ByVal
lpReturnedString As
String
, ByVal
nSize As
Long
) As
Long
Declare
Function
aht_apiGetPrivateProfileSection Lib
"kernel32"
Alias "GetPrivateProfileSectionA"
_
(
ByVal
lpAppName As
String
, ByVal
lpReturnedString As
String
, ByVal
nSize As
Long
, _
ByVal
lpFileName As
String
) As
Long
Declare
Function
aht_apiWritePrivateProfileString Lib
"kernel32"
Alias "WritePrivateProfileStringA"
_
(
ByVal
strAppName As
String
, ByVal
strKeyName As
String
, ByVal
strValue As
String
, _
ByVal
strFilename As
String
) As
Integer
Declare
Function
aht_apiWriteProfileString Lib
"kernel32"
Alias "WriteProfileStringA"
_
(
ByVal
strAppName As
String
, ByVal
strKeyName As
String
, ByVal
strValue As
String
) As
Integer
Type
aht_tagDeviceRec
drDeviceName As
String
drDriverName As
String
drPort As
String
End
Type
Type
aht_tagDEVMODE
dmDeviceName
(
1
To
32
) As
Byte
dmSpecVersion As
Integer
dmDriverVersion As
Integer
dmSize As
Integer
dmDriverExtra As
Integer
dmFields As
Long
dmOrientation As
Integer
dmPaperSize As
Integer
dmPaperLength As
Integer
dmPaperWidth As
Integer
dmScale As
Integer
dmCopies As
Integer
dmDefaultSource As
Integer
dmPrintQuality As
Integer
dmColor As
Integer
dmDuplex As
Integer
dmYResolution As
Integer
dmTTOption As
Integer
dmCollate As
Integer
dmFormName
(
1
To
32
) As
Byte
dmLogPixels As
Integer
dmBitsPerPixel As
Long
dmPelsWidth As
Long
dmPelsHeight As
Long
dmDisplayFlags As
Long
dmDisplayFrequency As
Long
dmICMMethod As
Long
dmICMIntent As
Long
dmMediaType As
Long
dmDitherType As
Long
dmICCManufacturer As
Long
dmICCModel As
Long
dmDriverExtraBytes
(
1
To
1024
) As
Byte
End
Type
Type
aht_tagDEVMODEStr
DMStr As
String
*
1024
End
Type
Type
aht_tagDEVNAMES
dnDriverOffset As
Integer
dnDeviceOffset As
Integer
dnOutputOffset As
Integer
dnDefault As
Integer
End
Type
Type
aht_tagDEVNAMEStr
DNStr As
String
*
4
End
Type
Type
aht_tagMIP
xLeftMargin As
Long
yTopMargin As
Long
xRightMargin As
Long
yBotMargin As
Long
fDataOnly As
Long
xFormSize As
Long
yFormSize As
Long
fDefaultSize As
Long
cxColumns As
Long
xFormSpacing As
Long
yFormSpacing As
Long
radItemOrder As
Long
fFastPrinting As
Long
fDataSheet As
Long
End
Type
Type
aht_tagMIPSTR
MIPStr As
String
*
28
End
Type
Function
ahtFillPrinterList
(
ctl As
Control, varID As
Variant
, varRow As
Variant
, varCol As
Variant
, varCode As
Variant
)
Static
atagDevices
(
) As
aht_tagDeviceRec
Static
intCount As
Integer
Dim
varRetval As
Variant
Select
Case
varCode
Case
acLBInitialize
intCount =
ahtGetPrinterList
(
atagDevices
(
))
varRetval =
True
Case
acLBOpen
varRetval =
Timer
Case
acLBGetRowCount
varRetval =
intCount
Case
acLBGetColumnCount
varRetval =
1
Case
acLBGetValue
varRetval =
atagDevices
(
varRow +
1
).drDeviceName
&
" sur "
&
_
atagDevices
(
varRow +
1
).drPort
Case
acLBEnd
Erase
atagDevices
End
Select
ahtFillPrinterList =
varRetval
End
Function
Function
ahtGetPrinterList
(
atagDevices
(
) As
aht_tagDeviceRec) As
Integer
Dim
astrPrinters
(
) As
String
Dim
intCount As
Integer
Dim
varPrinters As
Variant
varPrinters =
ahtGetProfileSection
(
"DEVICES"
)
If
Len
(
varPrinters &
""
) =
0
Then
ahtGetPrinterList =
0
Else
intCount =
GetDevices
(
varPrinters, atagDevices
(
))
End
If
ahtGetPrinterList =
intCount
End
Function
Private
Function
GetDevices
(
ByVal
strPrinters As
String
, atagDevices
(
) As
aht_tagDeviceRec) As
Integer
Dim
intI As
Integer
Dim
strBuffer As
String
Dim
intCount As
Integer
For
intI =
1
To
Len
(
strPrinters)
If
Mid
$(
strPrinters, intI, 1
) =
Chr
$(
0
) Then
intCount =
intCount +
1
End
If
Next
intI
ReDim
atagDevices
(
1
To
intCount)
For
intI =
1
To
intCount
strBuffer =
ahtGetToken
(
strPrinters, Chr
$(
0
), intI)
atagDevices
(
intI).drDeviceName
=
ahtGetToken
(
strBuffer, "="
, 1
)
strBuffer =
ahtGetToken
(
strBuffer, "="
, 2
)
atagDevices
(
intI).drDriverName
=
ahtGetToken
(
strBuffer, ","
, 1
)
atagDevices
(
intI).drPort
=
ahtGetToken
(
strBuffer, ","
, 2
)
Next
intI
GetDevices =
intCount
End
Function
Function
ahtGetDefaultPrinter
(
dr As
aht_tagDeviceRec) As
Boolean
Dim
strBuffer As
String
strBuffer =
ahtGetINIString
(
"Windows"
, "Device"
)
If
Len
(
strBuffer) >
0
Then
With
dr
.drDeviceName
=
ahtGetToken
(
strBuffer, ","
, 1
)
.drDriverName
=
ahtGetToken
(
strBuffer, ","
, 2
)
.drPort
=
ahtGetToken
(
strBuffer, ","
, 3
)
End
With
ahtGetDefaultPrinter =
True
Else
ahtGetDefaultPrinter =
False
End
If
End
Function
Function
ahtSetDefaultPrinter
(
dr As
aht_tagDeviceRec) As
Boolean
Dim
strBuffer As
String
strBuffer =
dr.drDeviceName
&
","
strBuffer =
strBuffer &
dr.drDriverName
&
","
strBuffer =
strBuffer &
dr.drPort
ahtSetDefaultPrinter =
(
aht_apiWriteProfileString
(
"Windows"
, _
"Device"
, strBuffer) <>
0
)
End
Function
Function
ahtGetToken
(
ByVal
strValue As
String
, ByVal
strDelimiter As
String
, ByVal
intPiece As
Integer
) As
Variant
Dim
intPos As
Integer
Dim
intLastPos As
Integer
Dim
intNewPos As
Integer
On
Error
GoTo
ahtGetTokenExit
strDelimiter =
Left
(
strDelimiter, 1
)
If
(
InStr
(
strValue, strDelimiter) =
0
) Or
(
intPiece <=
0
) Then
ahtGetToken =
strValue
Else
intPos =
0
intLastPos =
0
Do
While
intPiece >
0
intLastPos =
intPos
intNewPos =
InStr
(
intPos +
1
, strValue, strDelimiter)
If
intNewPos >
0
Then
intPos =
intNewPos
intPiece =
intPiece -
1
Else
intPos =
Len
(
strValue) +
1
Exit
Do
End
If
Loop
If
intPiece >
1
Then
ahtGetToken =
Null
Else
ahtGetToken =
Mid
$(
strValue, intLastPos +
1
, intPos -
intLastPos -
1
)
End
If
End
If
ahtGetTokenExit
:
Exit
Function
ahtGetTokenErr
:
MsgBox
"Error in ahtGetToken: "
&
Error
&
" ("
&
Err
&
")"
Resume
ahtGetTokenExit
End
Function
Function
ahtGetPrivateIniString
(
ByVal
strGroup As
String
, ByVal
strItem As
String
, ByVal
strFile As
String
) As
Variant
Dim
intChars As
Integer
Dim
strBuffer As
String
strBuffer =
String
(
MAX_SIZE, 0
)
intChars =
aht_apiGetPrivateProfileString
(
strGroup, strItem, ""
, strBuffer, MAX_SIZE, strFile)
ahtGetPrivateIniString =
Left
(
strBuffer, intChars)
End
Function
Function
ahtGetPrivateProfileSection
(
ByVal
strGroup As
String
, ByVal
strFile As
String
) As
Variant
Dim
strBuffer As
String
Dim
intCount As
Integer
strBuffer =
Space
(
MAX_SECTION)
intCount =
aht_apiGetPrivateProfileSection
(
strGroup, strBuffer, MAX_SECTION, strFile)
ahtGetPrivateProfileSection =
Left
(
strBuffer, intCount)
End
Function
Function
ahtGetProfileSection
(
ByVal
strGroup As
String
) As
Variant
Dim
strBuffer As
String
Dim
intCount As
Integer
strBuffer =
Space
(
MAX_SECTION)
intCount =
aht_apiGetProfileSection
(
strGroup, strBuffer, MAX_SECTION)
ahtGetProfileSection =
Left
(
strBuffer, intCount)
End
Function
Function
ahtGetINIString
(
ByVal
strGroup As
String
, ByVal
strItem As
String
) As
Variant
Dim
intChars As
Integer
Dim
strBuffer As
String
strBuffer =
String
(
MAX_SIZE, 0
)
intChars =
aht_apiGetProfileString
(
strGroup, strItem, ""
, strBuffer, MAX_SIZE)
ahtGetINIString =
Left
(
strBuffer, intChars)
End
Function
Function
ahtGetPrivateINIInt
(
ByVal
strGroup As
String
, ByVal
strItem As
String
, ByVal
strFile As
String
) As
Variant
ahtGetPrivateINIInt =
aht_apiGetPrivateProfileInt
(
strGroup, strItem, -
1
, strFile)
End
Function
Function
ahtGetINIInt
(
ByVal
strGroup As
String
, ByVal
strItem As
String
) As
Variant
ahtGetINIInt =
aht_apiGetProfileInt
(
strGroup, strItem, -
1
)
End
Function
Il faut utiliser le code suivant qui en fait reproduit par le code les manipulations que l'utilisateur doit effectuer afin d'obtenir l'effet escompté.
SendKeys "{f10}"
SendKeys "{f}"
SendKeys "{p}"
SendKeys "{right}"
SendKeys "%{y}"
SendKeys "{enter}"
Private
Sub
Report_Page
(
)
Me.Line
(
Me.ScaleWidth
/
2
, 0
)-(
Me.ScaleWidth
/
2
, Me.ScaleHeight
), 255
End
Sub
Aller plus loin.
Créez un nouvel état, en mode création, sans aucune source.
Allez dans le module de l'état, et copiez-y le code suivant :
Option
Compare Database
Private
Enum XY
x
y
End
Enum
Private
Sub
Report_Page
(
)
Dim
x1 As
Long
, x2 As
Long
Dim
y1 As
Long
, y2 As
Long
Dim
n As
Long
For
n =
1
To
255
x1 =
Banzai
(
x)
x2 =
Banzai
(
x)
y1 =
Banzai
(
y)
y2 =
Banzai
(
y)
c =
DefCouleur
Me.Line
(
x1, y1)-(
x2, y2), c
Next
End
Sub
Function
Banzai
(
xyType As
Long
) As
Long
Dim
MAX As
Long
Dim
n As
Long
Select
Case
xyType
Case
x
MAX =
Me.ScaleWidth
Case
y
MAX =
Me.ScaleHeight
End
Select
Banzai =
CLng
(
Rnd
(
) *
MAX)
End
Function
Function
DefCouleur
(
) As
Long
DefCouleur =
CLng
(
Rnd
(
) *
2
^
24
)
End
Function
Ouvrez l'état. Vous savez maintenant gribouiller un état.
Private
Sub
ZoneEntêtePage_Format
(
Cancel As
Integer
, FormatCount As
Integer
)
If
Me.Page
=
1
Then
Me.ZoneEntêtePage.Visible
=
False
Else
Me.ZoneEntêtePage.Visible
=
True
End
If
End
Sub
On fait une boucle sur le container "Reports" et on teste la longueur du nom de l'état ouvert courant, ce qui fait que si l'on ferme l'état, cela provoque une erreur que nous allons récupérer pour déclencher l'ouverture de l'état suivant.
Sub
ViewAllReports
(
)
Dim
iInt As
Integer
On
Error
GoTo
VARerrHandler
For
iInt =
0
To
CurrentDb.Containers
(
"Reports"
).Documents.Count
-
1
DoCmd.OpenReport
CurrentDb.Containers
(
"Reports"
).Documents
(
iInt).Name
, acViewPreview
Do
While
Len
(
Reports
(
0
).Name
) >
0
DoEvents
Loop
NextReport
:
Next
iInt
MsgBox
"Vous avez visualisé les "
&
iInt &
" états de la base"
, vbInformation
+
vbOKOnly
Exit
Sub
VARerrHandler
:
Select
Case
Err
.Number
Case
2457
Err
.Clear
Resume
NextReport
Case
Else
MsgBox
Err
.Number
&
vbCrLf
&
Err
.Description
Err
.Clear
End
Select
End
Sub
Dans un état multicolonne, vous ne pouvez pas mettre
un titre qui fait toute la largeur de la page, car la largeur d'un contrôle
ne peut pas dépasser la largeur d'une colonne.
Pour remédier à cela, il faut "écrire" le titre lors de l'impression de l'état.
Vous utiliserez l'instruction Print sur l'événement Page de l'état.
Private
Sub
Report_Page
(
)
Me.Print
"Je suis super www.developpez.com le forum d'entraide des développeurs francophones"
End
Sub