2012-08-04 120 views
5

我是Access新手,我來自C#,SQL Server & .Net。有一個項目是我的方式,我必須完成一些部分。如何通過Microsoft Access中的VBA設置INSERT SQL查詢的參數值?

的場景可以被描述爲:

  1. 一個訪問形式與窗體
  2. Access查詢是上述子窗體的數據源,使用兩個參數,顯示爲:Parametername1 String(255),Parametername2 String(255)
  3. VBA代碼模塊(一個或多個)

我的計劃是在我的VBA代碼模塊在過程內設置上述查詢參數的值。我相信這應該刷新我的子表單,因爲查詢是子表單的數據源。

問題是我不知道如何實施這個計劃。

我想使用查詢,因爲我不想用內聯SQL搞亂我的VBA代碼。

我使用Access 2010中

+0

VBA模塊中的內聯SQL不僅是出於可讀性的目的,也是因爲它可能會引發意外的錯誤並構成[安全威脅](http://xkcd.com/327/ )。 – StockB 2013-12-12 20:13:33

回答

6

我正是這個問題,我想用相同的「存儲」更新查詢,但由兩種不同的形式執行它這樣想的參數傳遞給在運行時查詢。這是我發現(在另一個論壇),那不正是我想要什麼什麼:

With CurrentDb.QueryDefs("qry_YourQuery") 
    .Parameters("yourParam") = yourVBAvar 
    .Execute 
End With 
+0

「qry_YourQuery」的外觀如何?你只是把'?'放在參數值應該去的地方嗎? – StockB 2013-12-12 17:03:45

+0

你有鏈接到論壇,你發現這個片段?我搜索,但我能找到的所有引用這篇文章。 – StockB 2013-12-13 14:49:12

+1

對於那些想知道的人。 「qry_YourQyery」是您在訪問數據庫的查詢列表中保存的查詢的名稱,如qryUpdateSalary。 「yourParam」是您在查詢中使用的參數的名稱,即Update tblSalary set Salary = salary * workhrs where PersonId = [person]。在這種情況下,參數是人,因此上面的示例看起來像 '代碼與CurrentDb.QueryDefs(「qryUpdateSalary」) .Parameters(「person」)= personID'此變量來自VBA代碼中的另一個步驟 。執行 End用' – kuklei 2014-07-03 16:27:22

2

子窗體的全部意義在於,它是由記錄源和鏈接兒童和主域控制。讓我們說的形式爲公司及子窗體爲員工,爲子窗體的記錄源可能是:

SELECT EmployeeID, CompanyID, Position, Etc FROM Employees 

鏈接子和主域將CompanyID。當您瀏覽主表單時,只會顯示與當前公司相關的記錄。讓我們說,你要顯示只有那些誰在技術崗位的員工,你可以在運行時更改的記錄源:

SELECT EmployeeID, CompanyID, Position, Etc FROM Employees 
WHERE Position = "Technical" 

或者,如果這是保持在窗體上的過濾器,添加組合框,說,主窗體和使用它作爲第二連接主機領域,所以你必須:

Link Master Fields: CompanyID; cboPosition 
Link Child Fields : CompanyID; Position 

最後,你可以簡單地設置過濾財產的主要形式:

Me.Employees_subform.Form.Filter = "Position=""Tecnical""" 
Me.Employees_subform.Form.FilterOn = True 

一世如果這不是你的想法,請在你的問題中添加一些註釋。

編輯

您可以通過表單上引用控制電源參數查詢:

SELECT EmployeeID, CompanyID, Position, Etc FROM Employees 
WHERE Position = Forms!MyMainForm!cboPosition 

您可以徹底改變一個查詢的SQL,您可以使用ADO,但是,更改SQL與設置記錄源的方式類似,因爲SQL在代碼中進行了更改,使用ADO通常不是表單的最佳選擇。

你不能做的是改變一個參數,讓它與表單或子表單「粘在一起」。

例如:

DoCmd.SetParameter "@SomeID", "1" 
' This works 
DoCmd.OpenQuery ("Queryx") 

' This will give a prompt for @SomeID and then run 
Me.SomeSubform.Form.RecordSource = "Queryx" 
+0

Remou謝謝。這將有助於確保。但我不想使用過濾器。我已經有一個查詢是子表單的記錄源。我需要知道,無論如何,我可以在VBA代碼中更改/設置查詢的參數。我正在尋找一種解決方案,在SQL Server中使用存儲過程,並在.net中使用SqlCommand(System.data.sqlclient)類。我甚至不知道這是否可能。否則,我只需將我的SQL嵌入到我的VBA代碼中,並將SQL狀態作爲我的記錄/數據源使用,然後繼續使用。訪問是不同的! – Romi24 2012-08-05 05:06:59

+0

訪問是不同的,主要的區別是,你可以做很多沒有任何代碼,這是人們經常忘記的東西。在這種情況下,查詢的參數應該來自一個表單,並且我指出了這種情況的發生方式。還有其他選項我錯過了,我會添加它們。 – Fionnuala 2012-08-05 07:36:56

+0

再次感謝Remou ......我認爲我們正在接近解決方案。唯一的是我不希望應用程序提示查詢中定義的參數。我想在我的VBA代碼中設置參數的值....以您的示例 - where position =「Technical」爲例,我想在我的VBA代碼中提供「Technical」的值 – Romi24 2012-08-05 08:33:42

1

你可以創建一個函數,並使用你的窗體的記錄源查詢功能(而不是常規參數)。

Public Function PositionParam(Optional ByVal P1 As Variant) As Variant 
    Static varP As Variant 

    If Not IsMissing(P1) Then 
     If IsNull(P1) Then 
      varP = Null 
     Else 
      varP = CStr(P1) 
     End If 
    ElseIf VarType(varP) = vbEmpty Then 
     varP = Null 
    End If 
    PositionParam = varP 
End Function 

記錄源查詢:

SELECT y.id_fld, y.another_fld, y.position_fld 
FROM YourTable AS y 
WHERE 
     y.position_fld = PositionParam() 
    OR PositionParam() Is Null 
ORDER BY y.id_fld, y.another_fld; 

後來,當你想在窗體顯示不同的行集,更改分配給PositionParam()Requery子窗體的值。

PositionParam "technician" 
Forms("YourForm").Requery 
+0

這可以工作。對我而言,我認爲我寧願從Remou建議的表單中獲取查詢參數。但是,由於您似乎不想這樣做,這是另一種方式。 – HansUp 2012-08-06 15:57:45

0

子窗體綁定到一個查詢和查詢不應該有任何參數都沒有。

您當然可以將子窗體的SQL存儲在查詢中,並且消除了內嵌的sql,但是隨後轉而編寫幾行代碼來解決此問題毫無意義。

如上所述,如果您從控件設置子鏈接和子設置,子窗體重新編碼的過濾和顯示是自動的,並且會發生無代碼的情況。您可能不需要任何代碼。

不過,如果你需要編寫代碼或想了解更多的計費時間,那麼你可以使用此代碼一些真正的原因是:

Dim strSql  As String 

strSql = Split(CurrentDb.QueryDefs("name of query").SQL, ";")(0) 

strSql = strSql & "where Field1 = " & "'your p1 value'" & _ 
        " and Field2 = " & "' your p2 value'" 

Me.custChild.Form.RecordSource = strSql 

所以你並不需要在SQL任何參數,但只使用當前和SAME查詢子表單基於。除了添加參數之外,您還可以在查詢中對2個值進行硬編碼,然後查詢不能用於其他代碼和任務,除非您提供2個SAME硬編碼參數(因此,在其他地方使用該查詢時幾乎沒有任何靈活性有不同的選擇)。

因此,請將參數留出查詢,並保留相同的金錢,時間和計費時間。

按照上面的說法提取查詢SQL並將條件添加到SQL是一件簡單的事情。但是,如果您希望將數據插入到子窗體中,則可以直接使用子窗體數據源和reocrdset。例如:

Dim rst  As DAO.Recordset 

    Set rst = Me.custChild.Form.RecordsetClone 

    rst.AddNew 
    rst!SomeField = "some valjue" 
    rst!SomeField2 = "some value" 
    rst.Update 

    Me.custChild.Requery