2008-09-18 8 views
3

J'aimerais pouvoir créer une requête paramétrée dans MS Access 2003 et alimenter les valeurs de certains former des éléments à cette requête, puis récupérer le jeu de résultats correspondant et faire quelques calculs de base avec eux. Je n'arrive pas à comprendre comment obtenir les paramètres de la requête à remplir par les éléments de formulaire. Si je dois utiliser VBA, c'est bien.Comment créer une requête paramétrée dans MS Access 2003 et utiliser d'autres requêtes/formulaires pour remplir les paramètres et obtenir un résultat

Répondre

0

Voici un extrait de code. Il met à jour une table à l'aide du paramètre txtHospital:

Set db = CurrentDb 

Set qdf = db.QueryDefs("AddHospital") 
qdf.Parameters!txtHospital = Trim(Me.HospName) 
qdf.ReturnsRecords = False 

qdf.Execute dbFailOnError 

intResult = qdf.RecordsAffected 

Voici un échantillon de SQL:

PARAMETERS txtHospital Text(255); 

INSERT INTO tblHospitals ( 
[Hospital]) 

VALUES ( 
[txtHospital]) 
0

Prenons un exemple. la requête paramétrées ressemble à ça:

Select Tbl_Country.* From Tbl_Country WHERE id_Country = _ 
    [?enter ISO code of the country] 

et que vous souhaitez être en mesure d'obtenir cette valeur (le [... entrer dans le pays?] une) d'une forme où vous avez vos commandes et certaines données dedans. Eh bien ... cela pourrait être possible, mais cela nécessite une normalisation du code.

Une solution consisterait à nommer vos contrôles de formulaire après une certaine logique, telle que fid_Country pour le contrôle qui contiendra une valeur id_Country. Votre peut alors avoir votre requête comme une chaîne:

qr = "Select Tbl_Country.* From Tbl_Country WHERE id_Country = [fid_country]" 

Une fois que vous avez saisi toutes les données demandées dans votre formulaire, appuyez sur le bouton « query ». La logique va parcourir tous les contrôles et vérifier si elles sont dans la requête, éventuellement remplacer le paramètre par la valeur du contrôle:

Dim ctl as Control 
For each ctl in Me.controls 
    If instr(qr,"[" & ctl.name & "]") > 0 Then 
     qr = replace(qr,"[" & ctl.name & "]",ctl.value) 
    End if 
Next i 

Ce faisant, vous aurez une requête entièrement mis à jour, où les paramètres ont été remplacés par des données réelles . En fonction du type de fid_country (chaîne, GUID, date, etc.), vous pourriez avoir à ajouter des guillemets supplémentaires ou non, pour obtenir une requête finale telle que:

qr = "Select Tbl_Country.* From Tbl_Country WHERE id_Country = ""GB""" 

Ce qui est une requête entièrement accès compatible vous pouvez utiliser pour ouvrir un jeu d'enregistrements:

Set rsQuery = currentDb.openRecordset(qr) 

Je pense que vous avez terminé ici.

Ce sujet est essentiel lorsque votre objectif est de développer des applications Access. Vous devez proposer aux utilisateurs un moyen standard d'interroger les données à partir de leur interface graphique, non seulement pour lancer des requêtes, mais aussi pour filtrer des formulaires continus (comme le fait Excel avec son option "autofilter") et gérer les paramètres des rapports. Bonne chance!

1

Il existe trois façons traditionnelles pour contourner ce problème:

  1. Nom du paramètre couperet quelque chose afin que l'utilisateur sera invité à entrer la valeur lorsque la requête est exécutée.
  2. Champ de référence sur un formulaire (éventuellement masqué)
  3. Générez la requête à la volée et n'utilisez pas de paramètres.

je pense qu'il est tout simplement faux de moi que vous ave d'injecter quelque chose comme [?enter ISO code of the country] ou des références à des champs sur votre formulaire comme: [Forms]![MyForm]![LastName]. Cela signifie que nous ne pouvons pas réutiliser la même requête dans plus d'un endroit, avec différents champs fournissant les données ou que nous devons compter sur l'utilisateur pour ne pas bloquer la saisie de données lorsque la requête est exécutée. Si je me souviens, il peut être difficile d'utiliser la même valeur plus d'une fois avec le paramètre entré par l'utilisateur.

En règle générale, j'ai choisi la dernière option a construit la requête à la volée, et mis à jour l'objet de requête selon les besoins. Cependant, cela est courant pour une attaque par injection SQL (accidentelle ou intentionnelle connaissant mes utilisateurs), et c'est juste icky.

J'ai donc fait quelques recherches et j'ai trouvé ce qui suit ici (http://forums.devarticles.com/microsoft-access-development-49/pass-parameters-from-vba-to-query-62367.html):

'Ed. Start - for completion of the example 
dim qryStartDate as date 
dim qryEndDate as date 
qryStartDate = #2001-01-01# 
qryEndDate = #2010-01-01# 
'Ed. End 

'QUOTEING "stallyon": To pass parameters to a query in VBA 
'      is really quite simple: 

'First we'll set some variables: 
Dim qdf As Querydef 
Dim rst As Recordset 

'then we'll open up the query: 
Set qdf = CurrentDB.QueryDefs(qryname) 

'Now we'll assign values to the query using the parameters option: 
qdf.Parameters(0) = qryStartDate 
qdf.Parameters(1) = qryEndDate 

'Now we'll convert the querydef to a recordset and run it 
Set rst = qdf.OpenRecordset 

'Run some code on the recordset 
'Close all objects 
rst.Close 
qdf.Close 
Set rst = Nothing 
Set qdf = Nothing 

(je n'ai pas testé moi-même, juste quelque chose que je collectionnais dans mes voyages, parce que chaque fois dans un certain temps, je « ai voulu faire cela, mais il a fini par utiliser un de mes bidouilles mentionnées précédemment)

Modifier J'ai eu enfin la cause de l'utiliser. Voici le code réel.

'... 
Dim qdf As DAO.QueryDef 
Dim prmOne As DAO.Parameter 
Dim prmTwo As DAO.Parameter 
Dim rst as recordset 
    '... 
    'open up the query: 
    Set qdf = db.QueryDefs("my_two_param_query") 'params called param_one and 
               'param_two 

    'link your DAP.Parameters to the query 
    Set prmOne = qdf.Parameters!param_one 
    Set prmTwo = qdf.Parameters!param_two 

    'set the values of the parameters 
    prmOne = 1 
    prmTwo = 2 

    Set rst = qdf.OpenRecordset(dbOpenDynaset, _ 
              dbSeeChanges) 
    '... treat the recordset as normal 

    'make sure you clean up after your self 
    Set rst = Nothing 
    Set prmOne = Nothing 
    Set prmTwo = Nothing 
    Set qdf = Nothing 
2

Les références aux contrôles du formulaire peuvent être utilisés directement dans les requêtes d'accès, mais il est important de les définir comme paramètres (sinon, les résultats dans les versions récentes d'accès peuvent être imprévisibles où ils étaient une fois fiables).

Par exemple, si vous souhaitez filtrer une requête par le contrôle sur LastName MonFormulaire, vous utiliseriez ce que vos critères:

LastName = Forms!MyForm!LastName 

Ensuite, vous devez définir la référence de formulaire en tant que paramètre. Le SQL résultant pourrait ressembler à ceci:

PARAMETERS [[Forms]!MyForm![LastName]] Text (255); 
SELECT tblCustomers.* 
FROM tblCustomers 
WHERE tblCustomers.LastName=[Forms]![MyForm]![LastName]; 

Je voudrais cependant vous demander pourquoi vous avez besoin d'avoir une requête enregistrée à cet effet. Que faites-vous avec les résultats? Les afficher dans un formulaire ou un rapport? Si c'est le cas, vous pouvez le faire dans la source de données du formulaire/rapport et laisser votre requête enregistrée intacte par les paramètres, de sorte qu'il peut être utilisé dans d'autres contextes sans ouvrir les invites pour remplir les paramètres. D'autre part, si vous faites quelque chose dans le code, écrivez simplement le SQL à la volée et utilisez la valeur littérale du contrôle de formulaire pour construire votre clause WHERE.

+0

David a raison. Vous pouvez utiliser la syntaxe qu'il a montrée pour référencer les contrôles de formulaire en tant que critères sans VBA du tout si vous voulez juste retourner les enregistrements et les résumer, etc. Si vous avez besoin de faire quelque chose de plus compliqué, je vous recommande également d'utiliser VBA & la propriété RecordSource à la volée. –

0

la méthode facile est ici Microsoft 'setparameter' info page

DoCmd.SetParameter "frontMthOffset", -3 
DoCmd.SetParameter "endMthOffset", -2 
DoCmd.OpenQuery "QryShowDifference_ValuesChangedBetweenSELECTEDMonths" 

où le SQL de la requête d'accès comprend [frontMthOffset] fait dans le SQL. par exemple.

"select blah from mytable where dateoffset=[frontMthOffset]" 

Tout fonctionne simplement!

Questions connexes