J'essaie de créer une macro qui lira les dates des cellules de ma feuille de calcul et les comparera à une date (mois et année) saisie dans un Userform. Pour ce faire, j'ai le Userform appeler un sous Report
trouvé dans Sheet1
. Les entiers qui représentent le mois et l'année entrés par l'utilisateur sont transmis avec l'appel.
L'erreur se produit toujours sur la ligne Call Sheet1.Report(intMonth, intYear)
:, qui appelle Report
. L'erreur se lit comme suit: Run-time error '1004': Application-defined or object-defined error
.
Voici mon code abrégé, commençant par Userform:
Private Sub cmdOK_Click()
'Transform month field into an integer (1-12)
Dim intMonth As Integer
Select Case cboMonth.Value
Case Is = strJan 'January - 01
intMonth = 1
Case Is = strFeb 'February - 02
intMonth = 2
Case Is = strMar 'March - 03
intMonth = 3
'and so on...
End Select
'Read year field as an Integer
Dim intYear As Integer
intYear = txtYear.Value
Call Sheet1.Report(intMonth, intYear)
End Sub
Ensuite, voici le code de Report
. Il est encore incomplet car je n'ai pas réussi à passer l'appel. Comme je l' ai mentionné plus tôt, j'ai toujours frappé l'erreur sur la ligne d'appel: Call Sheet1.Report(intMonth, intYear)
.
Public Sub Report(myMonth As Integer, myYear As Integer)
'Some incomplete code...
'Like I said, the macro never gets past the call.
End Sub
Une idée de comment réparer ça? Toute aide est très appréciée. Merci!
ThisWorkbook.Worksheets("Sheet1").Report intMonth, intYear
REMARQUE: vous n'avez pas besoin de l'Call
instruction si vous supprimez la parenthèse.Réponses:
Maintenant que vous avez prouvé que votre code fonctionne avec ma suggestion:
Prenons les conseils de Mathieu. Cliquez sur l'objet Feuille dans la vue Projet de votre fenêtre VBE:
La première partie est le nom de l'objet de la feuille, la deuxième partie entre parenthèses est le nom de la feuille de calcul, comme dans l'onglet Excel. Affichez la vue de la fenêtre Propriétés à partir du menu déroulant "Affichage" du VBE ou en appuyant sur F4. La première chose dans la fenêtre des propriétés de la feuille de calcul doit être (nom) et c'est le nom de l'objet que vous appelez dans votre code. Changez-le en quelque chose de descriptif comme "Rapport". Ensuite, utilisez un nom descriptif pour votre macro tel que "Mise à jour".
Vous pouvez maintenant créer un nouveau rapport en appelant:
J'utilise cette convention car je suppose que votre macro met à jour la feuille de rapport. Vous pouvez également suivre son avis sur le style de code "modèle-vue-présentateur", mais cela sort du cadre de votre question.
la source
Avoir une
UserForm
instance par défaut exécutant l’émission est peut-être la chose la plus facile à faire, mais c’est aussi une cause directe de beaucoup de problèmes - des bogues faciles à introduire, mais difficiles à trouver, aux problèmes de maintenance et d’extensibilité: solution rapide, fonctionne "est le modèle" Smart UI ", qui fonctionne génial pour un prototype . Les grands projets qui évoluent constamment avec le temps exigent une architecture plus intelligente.Les programmeurs l'appellent "model-view-presenter". La vue est la forme. Les données sont le modèle , et puis il y a le présentateur qui coordonne tout.
La vérité est que vous ne le faites pas. Un modal
UserForm
est un dialogue dont le rôle n'est rien de plus que de recueillir les données de l'utilisateur. En le rendant uniquement responsable de la manipulation des données et en laissant le macro / appelant responsable du flux de contrôle, vous rendez le code plus robuste et plus facile à gérer, en particulier si le formulaire peut faire beaucoup de choses.Commencez avec un
MonthlyReportParams
module de classe simple :Maintenant
UserForm
, il ne reste plus qu’à travailler avec ces données, ce modèle .Et maintenant, la macro qui ouvre ce formulaire peut reprendre le contrôle de ce qui se passe: le formulaire n’exécute plus le show, et nous pouvons lire tout ce qui se passe au même endroit:
Vous trouverez des informations supplémentaires sur les avantages de ce "renversement des responsabilités" dans cet article , ainsi qu'une logique de rappel dans cet article - disclaimer: j'ai écrit les deux; ce blog est le blog officiel du projet OSS complémentaire de Rubberduck VBIDE, que je possède.
la source
HackSlash a répondu à ma question:
Votre exemple de code a fonctionné pour moi. Gardez à l'esprit que votre utilisation de "Sheet1" en tant qu'objet est le nom de l'objet de la feuille et non le nom de la feuille de calcul visible sur l'onglet de la feuille Excel réelle. Si vous souhaitez l'appeler par le nom de la feuille de travail, essayez ceci: ThisWorkbook.Worksheets ("Sheet1"). Report intMonth, intYear REMARQUE: vous n'avez pas besoin de l'instruction Call si vous supprimez la parenthèse. - HackSlash Il y a 7 minutes
la source
ThisWorkbook
au moment de la compilation, définissez sa(Name)
propriété dans la fenêtre des propriétés (F4), en recherchant la feuille dans l' explorateur de projet (Ctrl + R). Ensuite, vous pouvez utiliser ce nom / identifiant dans le code pour faire référence à cette feuille, sans avoir besoin de la déréférencer d'uneWorksheets
collection, ni de déclarer une variable pour celle-ci.