2009-07-13 157 views
0

我正在嘗試使用VBA創建一個程序,該程序根據電子表格查詢我的oracle數據庫數據(在本例中爲管道),並在同一工作簿(但在另一個工作表上)生成綁定輸出。我想使用綁定頁面上的INDEX和MATCH函數,但無法解決這個問題。以下是我迄今爲止(以下圖示),這裏是我的問題:如何使用INDEX和MATCH函數與VBA,Oracle和Excel結合?

我有:
我有我的工作簿4個選項卡:
1.電子表格數據
2.說明(提示用戶輸入管道,查詢結束/開始日期)
3.數據庫輸出數據(VBA腳本將從Oracle數據庫中提取數據)
4.列出數據選項卡(這是我遇到的問題)

問題:
1)如何使用INDEX和MATCH查找Oracle數據庫表和我的電子表格中的查找值?
2)我可以如何創建一個下拉框,以便用戶選擇一個管道,而不是將管道提供給用戶?這將減少任何用戶輸入錯誤(如拼寫等)。

謝謝!

alt text http://i27.tinypic.com/260plvn.jpg

alt text http://i26.tinypic.com/1zznqrt.jpg

我的代碼:

Option Explicit 
Option Base 1 
'user is prompted for dates and pipeline name 
'click button will prompt query 

Dim cnnObject As ADODB.Connection 
Dim rsObject As ADODB.Recordset 
Dim strGPOTSConnectionString As String 
'this will remove old sql data upon new query 

Dim ws As Worksheet 

Dim Pipeline As String 
Dim DateStart As Date 
Dim DateEnd As Date 
Dim strQuery As String 

Sub Say(s As String) 
    Debug.Print s 
End Sub 

Sub ClickButton2() 

    Debug.Print ("Button has been clicked") 

    'KGK 
    Set ws = Worksheets("ZaiNet Data") 
    ws.UsedRange.Clear '' remove results of previous query if any 
    'this will fill in null values in query as "data not available" 

    Pipeline = InputBox("Enter PipeLine", "My Application", "Default Value") 
    DateStart = InputBox("Enter Start Date", "My Application", DateTime.Date) 
    DateEnd = InputBox("Enter End Date", "My Application", DateTime.Date + 1) 

    Range("B1").Value = Pipeline 
    Range("B2").Value = DateStart 
    Range("B3").Value = DateEnd 

    'KGK: call to function to populate the IN() part of the SQL statement 
    Dim dtInDate As String 
    dtInDate = GetIN(DateStart, DateEnd) 

    Debug.Print (" ") 

    'strQuery = "select pipelineflow.lciid lciid, ldate, volume, capacity, status, " & _ 
     "pipeline, station, stationname, drn, state, county, owneroperator, companycode, " & _ 
     "pointcode, pointtypeind, flowdirection, pointname, facilitytype, pointlocator, " & _ 
     "pidgridcode from pipelineflow, pipelineproperties " & _ 
     "where pipelineflow.lciid = pipelineproperties.lciid " & _ 
     "and pipelineflow.audit_active = 1 " & _ 
     "and pipelineproperties.audit_active =1 " & _ 
     "and pipelineflow.ldate >= '" & Format(DateStart, "m/d/yyyy") & "' and pipelineflow.ldate < '" & Format(DateEnd, "dd-MMM-yyyy") & "' " & _ 
     "and pipelineproperties.pipeline = '" & Pipeline & "' " 

    strQuery = "select pipelineflow.lciid lciid, ldate, volume, capacity, status, " & _ 
     "pipeline, station, stationname, drn, state, county, owneroperator, companycode, " & _ 
     "pointcode, pointtypeind, flowdirection, pointname, facilitytype, pointlocator, " & _ 
     "pidgridcode from pipelineflow, pipelineproperties " & _ 
     "where pipelineflow.lciid = pipelineproperties.lciid " & _ 
     "and pipelineflow.audit_active = 1 " & _ 
     "and pipelineproperties.audit_active =1 " & _ 
     "and pipelineflow.ldate " & dtInDate & _ 
     "and pipelineproperties.pipeline = '" & Pipeline & "' " 

    'KGK: modify strQuery 

    'Debug.Print (strQuery) 

    Call PullZaiNetData(strQuery) 

    Call TieOut 

End Sub 

Sub PullZaiNetData2(ByVal strQry As String) 

    Set cnnObject = New ADODB.Connection 
    Set rsObject = New ADODB.Recordset 

    strGPOTSConnectionString = "DRIVER={Microsoft ODBC for Oracle}; SERVER=XXX; PWD=XXX; UID=XXX" 


    cnnObject.Open strGPOTSConnectionString 

    'this will give a record count and will help to verify values 

    'rsObject.Open strQry, cnnObject, adOpenStatic 
    'Say rsObject.RecordCount & " records" 
    'If rsObject.RecordCount = 0 Then 
    ' ws.Cells(1, 1) = "DATA NOT AVAILABLE" 
    'Else 
    ' ws.Cells(1, 1).CopyFromRecordset rsObject 
    'End If 

    rsObject.Open strQry, cnnObject, adOpenStatic 
    Worksheets("ZaiNet Data").Cells(1, 1).CopyFromRecordset rsObject 


    rsObject.Close 
    cnnObject.Close 

    Set rsObject = Nothing 
    Set cnnObject = Nothing 

End Sub 

Sub TieOut() 
    Dim i As Integer 
    Dim j As Integer 

    For i = 1 To 3 
     For j = 1 To 3 
      Worksheets("TieOut").Cells(i, j).Value = "'=INDEX('database data for all dates '!$A$1:$U$314,MATCH(AH$4&TEXT($B8,""m/dd/yyyy""),'database data for all dates '!$C$1:$C$314,0),4)" 
     Next j 
    Next i 

End Sub 

Public Function GetIN(ByVal startDate As Date, ByVal endDate As Date) As String 

    Dim arrDates() As Date 
    Dim currentDate As Variant 
    Dim dateInterval As Integer 
    Dim strIN As String 
    Dim i As Integer 

    dateInterval = DateDiff("d", startDate, endDate) 
    dateInterval = dateInterval + 1 
    ReDim arrDates(1 To dateInterval) 

    For i = 1 To dateInterval 
     arrDates(i) = DateAdd("d", i - 1, startDate) 
    Next i 

    'debug loop 

    'For i = 1 To dateInterval 
    ' Debug.Print ("i: " & i & ", date: " & arrDates(i)) 
    'Next i 

    'Convert the date array to string 

    strIN = " IN(" 

    For i = 1 To UBound(arrDates) 
     strIN = strIN & "'" & CStr(Format(arrDates(i), "m/d/yyyy")) & "'" 
     If i < UBound(arrDates) Then 
      strIN = strIN & ", " 
     End If 
    Next 

    strIN = strIN & ") " 

    'debug statement 
    'Debug.Print (strIN) 

    GetIN = strIN 

End Function 
+0

re:創建下拉框。管道名稱來自哪裏:在工作表上硬編碼還是從數據庫中讀取? – barrowc 2009-07-13 23:10:45

回答

0

Q1。看起來您正在嘗試進行某種日期匹配,但沒有看到實際的表單,要提供精確的表達式有點困難。

但也有一些想法:

  • 你可能已經知道這一點, 但你需要更改單元(i, j)的.value的,以單元(i,j)的.Formula和 擺脫在 之前的撇號「= INDEX」如果你想讓你的公式到 實際工作。
  • 在你MATCH函數,你 尋找AH $ 4 & TEXT($ B8 「」 M/DD/YYYY 「」 這看起來 有點懷疑我了。什麼是 細胞AH $ 4〜請問甲骨文吐出一些 很怪前綴的日期之前?如果您 剛剛平原日期在 細胞,你就不需要擔心 左右格式(你可以得到TEXT的擺脫 ,只是做一個純粹的 比較)。Excel將日期存儲爲 「serial」編號。另外,請查看DATEVALUE上的幫助 。 ver到 純日期。
  • 只是一般建議。獲取 MATCH表達式首先工作。 然後嘗試將MATCH 表達式插入到INDEX表達式中。 這將幫助你隔離你的 確切的問題。

Q2。看起來您的工作表中已有管道列表,因此您可以創建驗證,以確保用戶只選擇合法的管道。

  • 爲您的列表 管道指定一個名稱。您可以通過選擇 管道列表來執行此操作,請單擊 從 的公式選項卡中定義名稱,然後輸入名稱。
  • 在工作表上選擇一個單元格用於 用戶選擇管線。
  • 單擊功能區數據選項卡 上的數據驗證。
  • 對於允許,請選擇列表。
  • 對於Source,輸入等號 ,後跟您爲管道列表分配的名稱 。所以,如果你的名字是Pipelines,你可以輸入 =管道。

現在,當用戶單擊該單元格時,只有管道將出現在該單元格中。