FAQ MS-Access

FAQ MS-AccessConsultez toutes les FAQ
Nombre d'auteurs : 140, nombre de questions : 926, dernière mise à jour : 15 juin 2021
Sommaire→États→États Trucs et Astuces- 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 SubLien : 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 FunctionFonction 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 FunctionSECTION 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 FunctionIl 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 SubAller 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 FunctionOuvrez 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 SubDans 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


