2010-05-15 1 views
4

VBA를 사용하여 Access 2007 쿼리에서 매개 변수를 설정하는 방법이 있는지 알고 싶습니다. Access에서 VBA를 처음 사용하고 있으며 기존 앱에 기능을 추가하는 작업을 수행했습니다.보고서의 공개 이벤트에 매개 변수를 매개 변수 쿼리에 전달 (Access 2007)

내가 겪고있는 문제는 응용 프로그램의 두 곳에서 같은 보고서를 호출 할 수 있다는 것입니다. 첫 번째는 데이터 입력 양식의 명령 단추에 있고, 다른 하나는 교환 단추입니다. 보고서 자체는 사용자가 공급자 ID를 입력해야하는 매개 변수 쿼리를 기반으로합니다.

사용자는 데이터 입력 양식에 Supplier ID를 입력하지 않아도되지만 (양식에 Supplier ID가 이미 표시되어 있기 때문에), 교환기에서 Supplier ID를 입력하라는 메시지가 표시됩니다.

내가 멈추는 곳은 보고서의 공개 이벤트에서 보고서의 쿼리를 호출하고 양식에서 SupplierID를 매개 변수로 전달하는 방법입니다. 나는 잠시 동안 노력해 왔고, 나는 올바르게 작동하는 것을 얻을 수 없다. 지금까지 제 코드가 있습니다 만, 분명히 난처한 상황입니다.

개인 서브 Report_Open (정수로 취소)

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 

최종 하위는

나는 Me.SupplierID = intSupplierCode을 시도했습니다, 그리고 그것을 컴파일하지만, 폭탄 나는 그것을 실행할 때. 다음은 매개 변수 쿼리에 대한 내 SQL 코드입니다.

매개 변수 [공급 업체] Long; SELECT Suppliers.SupplierID, Suppliers.CompanyName, Suppliers.ContactName, Suppliers.ContactTitle 공급자로부터 WHERE (((Suppliers.SupplierID) = [Supplier] 입력)));

나는이 문제를 해결할 수있는 방법이 있다는 것을 안다.하지만 내가 말했듯이, Access와 VBA를 사용하는 나의 경험 부족으로 상황이 어려워진다. 당신 중 누구라도 도울 수 있다면, 좋을 것입니다!

답변

7

여기에서 제안하는 것은 100 % 쿼리에서 매개 변수를 제거하는 것입니다. 이것은 당신의 문제를 해결할뿐만 아니라, 코드, 다른 형식에 대한 쿼리를 사용할 수 있다는 것을 의미하며, 하나의 어리석은 양식이 열려 있지 않기 때문에 전체 디자인이 붕괴되지 않습니다 (따라서 질문에 대한 매우 이유가 있음).

따라서 쿼리에서 매개 변수를 제거하십시오. 즉, 보고서에 이미 열려있는 양식이 필요하지 않습니다. 그리고 바보 같은 형태가 열리지 않는다면 왜 보고서가 제대로 작동하지 않을까요?

매개 변수를 제거하십시오. 이제 보고서를 여는 양식에서 필터를 전달할 수 있으며 더 많은 부분에서 호출 된 "where"절이 사용됩니다. 이 "where"절은 필요한 매개 변수와 필터의 종류를 미리 알 필요가있는 문제를 해결하기 위해 MS 액세스에서 설계되었습니다. 런타임에 발생하므로 많은 다른 양식이 해당 보고서를 호출하고 열 수 있습니다.

지금 호출하고 폼을 여는 형태로, 당신은 갈 :

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

그래서, 위의 매개 변수는 즉석에서 생성됩니다. 가장 큰 이점은 내일 다른 양식에서 동일한 보고서를 열고 아마도 지역별로 필터링 할 수 있다는 것입니다.

where 절이 전달되고 사용자가 양식을 열면 필터가 사용되지 않고 프롬프트가 나타나지 않고 모든 레코드가 표시됩니다. 아마도 이것이 최선의 접근 방법 일 것입니다.

그러나 어리석은 양식이 열리지 않을 때 몇 가지 보고서 프롬프트가 필요하다고 여겨지는 이상한 이유가있는 경우 양식 온에어 이벤트에 다음 코드를 추가하십시오.

그러나 보고서 열림 이벤트에서 어리석은 양식 이름을 하드 코딩하는 것을 피하기 위해 노력할 것입니다. 이것은 현재 보고서에 첨부 된 바보 같은 형식의 하드 코딩 종속성을 의미 할뿐만 아니라 나중에 해당 보고서를 복사하거나 원본 양식을 복사하거나 심지어 이러한 개체의 이름을 바꾼다면 응용 프로그램으로 가서 사냥을하고 개발자가 의존성을 도입 한 장소를 찾습니다. 이 접근법은 응용 프로그램의 유지 관리 비용을 크게 증가시킬 수 있으므로이를 개선해야합니다.

그래서 제안 사항은 매개 변수 쿼리를 덤프하는 것입니다. 보고서를 실행하기위한 양식이나 프롬프트 시스템을 제공하기 만하면됩니다. 이러한 양식은 사용자가 필터링하려는 정보를 요구해야합니다. 또는 귀하의 경우에는 바인딩 된 양식과 현재 기록이 해당 정보를 제공합니다. 이 시스템의 아름다움은 현재 보고서에서 불만이 없다는 것입니다.

길 아래에있는 어떤 양식이나 코드라도 Pramaeter를 무료로 전달할 수 있으며 SupplierID에 국한되지 않고 원하는 유형의 필터 또는 매개 변수가 될 수 있습니다.

아마도 사용자는 해당 양식을 열지 않고 프롬프트를 원하지 않을 수도 있습니다. 설계 및 질문을 통해 사용자는 서식을 열지 않고도 보고서를 시작할 때도 매개 변수 값을 입력해야하며 해당 보고서의 모든 reocrd를 볼 수있게하려면 프롬프트되지 않아도됩니다.

+0

OnOpen에서 기준 양식에 대한 참조를 절대로 강구하지 않을 것을 권장합니다. 항상 그렇습니다. 기준 양식을 무시할 수있는 몇 가지 방법을 제공하려는 몇 가지 사례에서 저는 A2003 이상에서 OpenArgs를 사용하고 WhereCondition을 제공하고 OnOpen의 보고서의 .Filter 속성을 확인하여 양식 열기를 건너 뜁니다. –

+0

감사합니다. Albert. 귀하의 조언은 좋았지 만 결국에는 솔루션 데이비드에 대한 내 의견에서 언급했듯이 어쨌든,이 티켓을 잠시 동안 작업 한 후에는 티켓을 너무 많이 사용해야하는 시점에 도달해야합니다. 그러면 다시이 앱은 끔찍한 혼란 때문에 그냥 폐기하고 다시 제출하십시오 ... 어쨌든, 조언을 주셔서 다시 한번 감사드립니다. David에 대한 제 응답에서 언급했듯이, 저는 여기에서 새로 왔기 때문에, 아직 당신을 투표 할 수는 없습니다. – JPM

+0

저는 솔직히 "리팩토링에 대한 전체 팬이 아니므로 응답해야한다고 생각하는대로 완료되었습니다." 이는 베스트 프랙티스에 대한 좋은 설명 일지 모르지만 실제로는 전혀 대답하지 않습니다. – Hill

3

a recent post에 개략적으로 설명했듯이 나는 매개 변수 나 양식 참조를 보고서 또는 양식의 레코드 소스로 연결하지 않습니다. 대신 런타임에 설정했습니다. 가장 간단한 방법은 DoCmd.OpenForm/DoCmd.OpenReport의 WhereCondition 속성을 통과하는 것입니다 :

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

당신이 (의 레코드 원본에 이미 존재하는 관련 공급 업체 ID가있는 양식에서 그것을 실행하고 가정 즉, 당신 SupplierID를 가진 기록에).

더 복잡한 것은 보고서의 레코드 원본을 설정하기 위해 보고서의 OnOpen 이벤트를 사용하는 것입니다. 그게 내가 in the cited post above의 윤곽선입니다. 그러나이 예제는 선택 사항을 선택 양식으로 고정시키는 반면 문맥에 따라 다양한 선택 세트를 제공 할 수 있습니다.

  1. A2003 경우 이상 OpenArg합니다 (DoCmd.OpenReport의 마지막 매개 변수)을 전달하는 필터링 무엇에 대한 정보를 수집하기 위해 무엇을해야 하는지를의 OnOpen 이벤트를 알려줄 수 : 그 처리 방법은 두 가지가 있습니다 .

  2. 은 독립 실행 형 클래스 모듈과 같은 외부 구조를 사용하여 OnOpen 이벤트가 읽고 그에 따라 행동하는 기준을 저장합니다.

은 내가 DoCmd.OpenReport의 WhereCondition이 가장 쉬운 해결책이 의심하지만 다른 두에 대한 자세한 내용을 원하는 경우, 단지 부탁드립니다.

+0

응답 해 주셔서 감사합니다. 그러나 경험 부족이 실제로 나타나기 때문에 사과해야합니다. 보고서의 Open 이벤트에서 데이터 입력 폼이 열려 있지 않은 경우에만 보고서의 레코드 원본 쿼리에 대한 매개 변수 프롬프트를 실행하고 싶습니다. 데이터 입력 양식이 열려 있으면 양식 자체에서 공급 업체 ID를 가져옵니다. 나는 아직도 갇혀있다. 내가 무엇을 할지라도 매개 변수 프롬프트는 여전히 보여 지거나 완전히 폭탄을 투하하기 때문이다. 제안한 코드를 시도했지만 SupplierID에 대한 메시지가 계속 나타납니다. 나는 OpenArgs에 익숙하지 않다. – JPM

+0

나는 보고서의 레코드 소스에서 매개 변수를 완전히 제거하고 대신 원하는 값을 수집하여 DoCmd.OpenReport의 WhereCondition에 제공하는 것이 좋습니다. 이것은 훨씬 간단하고 보고서의 외부 개체에 대한 종속성을 제거합니다. 보고서를 열어 모든 레코드를 표시하거나 런타임에 원하는 모든 레코드 세트로 필터를 필터 할 수 있습니다. 앨버트는 그의 답변에서이 모든 것을 아주 잘 설명해주었습니다. –

+0

David에게 감사드립니다. 나는 이것을 멘토와 함께 기증했다. (나는 여름 학생회에서 일하는 대학생이다.) 현재 존재하는 의존성을 제거하는 것이 타당하지만 해결책은 두 가지 질의를 생성하는 것이었다. 데이터 입력 양식이 열려 있으면 그에 따라 보고서의 레코드 소스를 적용하십시오. 못생긴하지만이 앱도 마찬가지입니다. 이름 지정 표준이 전혀 존재하지 않습니다. 이름이 처음으로 명명 된 경우에도 마찬가지입니다. Text39와 CommandButton291을 다루는 것은 상황을 충분히 어렵게 만들고 있습니다. 그러나 결국, 나는 내가 말한 것을한다 ... – JPM