2010-05-15 3 views
4

Я хотел бы знать, есть ли способ установить параметры в запросе Access 2007 с помощью VBA. Я новичок в использовании VBA в Access, и мне было поручено добавить немного функциональности в существующее приложение.Передача параметра в открытое событие отчета в запрос параметра (Access 2007)

Проблема, с которой я сталкиваюсь, заключается в том, что тот же отчет можно вызвать в двух разных местах приложения. Первый - на кнопке команды в форме ввода данных, другой - на кнопке коммутатора. Сам отчет основан на запросе параметра, который требует от пользователя ввода идентификатора поставщика.

Пользователь не хотел бы вводить идентификатор поставщика в форме ввода данных (поскольку форма уже отображает идентификатор поставщика), но из коммутатора им будет предложено ввести идентификатор поставщика.

Где я застрял - как вызвать запрос отчета (в открывшемся событии отчета) и передать идентификатор ProviderID из формы в качестве параметра. Я пытался какое-то время, и я не могу заставить что-то работать правильно. Вот мой код до сих пор, но я явно тупик.

Private Sub Report_Open (Отмена As Integer)

Dim intSupplierCode As Integer 

'Check to see if the data entry form is open 
If CurrentProject.AllForms("frmExample").IsLoaded = True Then 

    'Retrieve the SupplierID from the data entry form 
    intSupplierCode = Forms![frmExample]![SupplierID] 

    'Call the parameter query passing the SupplierID???? 
    DoCmd.OpenQuery "qryParams" 


Else 

    'Execute the parameter query as normal 

    DoCmd.OpenQuery "qryParams"????? 


End If 

End Sub

Я попытался Me.SupplierID = intSupplierCode, и хотя он собирает, это бомбы, когда я запускаю его. И вот мой код SQL для запроса параметра:

ПАРАМЕТРЫ [Ввод поставщика] Длинный; ВЫБОР Поставщиков.Покупщик, Поставщики.КомпанияИмя, Поставщики.Контактное имя, Поставщики.ContactTitle ОТ Поставщиков ГДЕ (((Поставщики.Поставщик) = [Вход Поставщика]));

Я знаю, что есть способы обойти эту проблему (и, вероятно, простой способ), но, как я уже сказал, мой недостаток опыта использования Access и VBA затрудняет работу. Если бы кто-нибудь из вас мог помочь, это было бы здорово!

ответ

7

Предлагаемое здесь предложение - 100% УДАЛИТЬ параметр из запроса. Это не только решает вашу проблему, но и означает, что вы можете использовать запрос для кода, других форм и не иметь размывания всей вашей конструкции, потому что одна глупая форма не открыта (следовательно, ОЧЕНЬ причина вашего вопроса).

Итак, удалите параметры из запроса. Это также означает, что вашему отчету теперь не потребуется какая-то форма, которая уже открыта. И снова, если какая-то глупая форма не открывается, почему ваш отчет не работает?

Итак, удалите параметр. Теперь, в вашей форме, которая открывает отчет, он может передать фильтр, а больше использовать то, что называется предложением «где». Это предложение «where» разработано в MS-доступе, чтобы решить проблему того, что нужно заранее знать, какие параметры и фильтры вам нужны. Это происходит во время выполнения, и поэтому МНОГИЕ РАЗНЫЕ формы могут вызывать и открывать этот отчет.

В настоящее время в форме, которая вызывает и открывает форму, вы идете:

Docmd.OpenReport "rptSuppliers",acViewPreview, , _ 
       "SupplierCode = " & me.SupplierCode 

Так, в приведенном выше, параметр создается на лету. Большим преимуществом является то, что завтра вы можете иметь другую форму, открывать тот же отчет и, возможно, фильтровать по регионам.

В случае передачи предложения NO where и пользователя, просто открывающего форму, никакие фильтры не будут использоваться, и никаких запросов не будет, и все записи будут отображаться. Вероятно, это ваш лучший подход.

Однако, если по какой-то странной причине вы по-прежнему считаете, что необходимо, чтобы у вас было какое-то сообщение, когда одна глупая форма просто не открывается, тогда поместите следующий код в открытое событие формы.

If CurrentProject.AllForms("form1").IsLoaded = False Then 
    Me.Filter = "SupplierID = " & InputBox("Enter Supplier ID") 
    Me.FilterOn = True 
End 

Однако я бы действительно прилагал усилия, чтобы избежать жесткого кодирования некоторого глупого имени формы в открывшемся событии отчетов. Это не только означает, что ваши жесткие кодировки зависят от какой-то глупой формы, которая теперь привязана к отчету, но если вы позже скопируете этот отчет или даже скопируете оригинальную форму (или даже переименуете любой из этих объектов), тогда вам придется заходите в приложение и охотитесь за и теперь находите места, где вы как разработчик вносили зависимости. Такой подход может существенно увеличить затраты на обслуживание приложения и, следовательно, следует рекомендовать.

Итак, предложение здесь - сбросить запрос параметра. Просто создайте форму или какую-нибудь оперативную систему для запуска отчетов. Эти формы должны запрашивать у пользователя информацию, которую вы хотите фильтровать. Или, как в вашем случае, связанная форма и текущая запись предоставляют эту информацию. Красота этой системы теперь не отражается на отчете.

Любая форма или даже любой код по дороге может свободно передавать праймер, и он не будет ограничиваться только поставщикомID, но может быть любым фильтром или параметром, который вы хотите.

Имейте в виду, что, возможно, пользователю может не понадобиться открывать эту форму и, возможно, они не хотят приглашения. С вашим дизайном и вопросом пользователь будет вынужден ввести значение параметра даже при запуске отчета без каких-либо форм, открытых и не желающих, чтобы им было предложено разрешить им просматривать все реордсы в этом отчете.

+0

Я думаю, что вы рекомендуете никогда не ссылаться на форму критериев в OnOpen, завышенную. Я делаю это все время. В тех немногих случаях, когда я также хочу предоставить некоторый метод обхода формы критериев, я использовать OpenArgs в A2003 и более поздних версиях, а также предоставить WhereCondition и проверить свойство отчета .Filter в OnOpen, чтобы пропустить открытие формы. –

+0

Спасибо, Альберт. Ваш совет был замечательный, но в конце мне сказали, чтобы я пошел с решение, о котором я упомянул в своем комментарии Дэвиду. В любом случае, после работы над этим билетом какое-то время он дошел до того момента, когда время заставить его работать так, как должно быть, было бы слишком большим для билета. просто надо сложить и переделать, так как это ужасный беспорядок ... В любом случае, еще раз спасибо за совет. Как я уже упоминал в своем ответе Дэвиду, я здесь новый, поэтому я тоже не могу проголосовать. – JPM

+0

Я, честно говоря, не большой поклонник «рефакторирования всего вашего приложения, так что это было так, как я думаю, это должно быть» ответы. Это может быть хорошим комментарием по передовым методам, но на самом деле он вообще не отвечает на вопрос. – Hill

3

Как я изложил в a recent post, я, как правило, никогда не устанавливал никаких параметров или не составлял контрольные ссылки в источниках отчетов или форм. Вместо этого я устанавливаю их во время выполнения. Самый простой способ, передавая свойство WhereCondition в DoCmd.OpenForm/DoCmd.OpenReport:

DoCmd.OpenReport "MyReport", , , "[SupplierID]=" & Me!SupplierID 

Это предполагает, что вы используете его из формы, имеющей соответствующую SupplierID уже присутствует в RecordSource (то есть, вы 're на записи с этим ProviderID).

Более сложным является использование события OnOpen отчета для установки источника записей отчетов. Вот что я изложил in the cited post above. Но этот пример затрудняет выбор формы выбора, тогда как вы можете вместо этого предлагать различные варианты выбора в зависимости от контекста. Есть два способа обработки, что:

  1. если A2003 и позже, сдали OpenArg (последний параметр DoCmd.OpenReport), чтобы сказать событие OnOpen, что нужно сделать, чтобы собрать информацию о том, что фильтр для ,

  2. использовать внешнюю структуру, такую ​​как автономный класс, чтобы хранить критерии, которые событие OnOpen будет читать и действовать соответственно.

Я подозреваю, что WhereCondition в DoCmd.OpenReport ваше самое простое решение, но если вы хотите подробную информацию о двух других, просто спросить.

+0

Спасибо за ответ Дэвид. Но я думаю, что мой недостаток опыта действительно демонстрируется, поэтому я должен извиниться. Я бы хотел, чтобы это произошло в открывшемся событии Отчета, выпустите приглашение параметра к запросу источника записи отчета только в том случае, если форма ввода данных не открыта. Если форма ввода данных открыта, просто возьмите Идентификатор поставщика из самой формы. Я все еще застрял, потому что независимо от того, что я делаю, подсказка параметра все еще показывает или полностью бомбит. Я пробовал строку кода, которую вы предложили, но я все еще получаю запрос на RequestID. Я, однако, не знаком с OpenArgs. – JPM

+0

Я предлагаю вам полностью удалить параметры из источника записей отчета и вместо этого собрать нужные значения и предоставить их в WhereCondition of DoCmd.OpenReport. Это намного проще и удаляет любую зависимость от внешних объектов из отчетов. Он позволяет открывать отчет, чтобы показывать все записи, или фильтровать его на любой набор записей, которые вам нравятся во время выполнения. Альберт объяснил все это вполне хорошо в своем ответе. –

+0

Спасибо, Дэвид. Я воспитывал это со своим наставником (я студент колледжа, работающим над моей летней кооперативной позицией), и хотя имеет смысл удалить существующие зависимости, решение заключалось в том, чтобы создать два запроса и зависело от того, форма ввода данных открыта, соответствующим образом применяйте источник записи отчета. Это уродливо, но и это приложение. Нет абсолютно никаких стандартов именования, и это, если их даже называют для начала. Работа с кучей Text39 и CommandButton291 делает вещи достаточно сложными, как есть. Но в конце концов, я делаю то, что мне говорят ... – JPM