Как связать VBA, Oracle и Excel с помощью функций INDEX & MATCH? - PullRequest
0 голосов
/ 13 июля 2009

Я пытаюсь создать программу, использующую VBA, которая запрашивает данные моей базы данных оракула (в данном случае конвейеры) по электронной таблице и создает вывод связки в той же книге (но на другом листе). Я хотел бы использовать функции INDEX и MATCH на странице раскладки, но не могу понять это. Вот что у меня есть (графическое изображение ниже) и вот мои вопросы:

ЧТО Я ИМЕЮ:
В моей книге 4 вкладки:
1. Электронная таблица данных
2. Инструкции (где пользователю предлагается указать конвейер, даты окончания / начала запроса)
3. Выходные данные базы данных (скрипт VBA извлекает данные из базы данных Oracle)
4. Свяжите вкладку данных (вот где у меня проблемы)

Вопросы:
1) Как сделать связующую страницу, используя INDEX и MATCH, поиск значений из моего листа базы данных Oracle и моей электронной таблицы?
2) Вместо того, чтобы ЗАПРОСИТЬ пользователю конвейер, как я могу создать раскрывающийся список, чтобы пользователь выбирал ОДИН конвейер? Это уменьшит любые ошибки ввода пользователя (такие как орфография и т. Д.).

Спасибо!

alt text

alt text

МОЙ КОД:

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

1 Ответ

0 голосов
/ 14 июля 2009

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

Несколько мыслей:

  • Вы, наверное, уже знали это, но вам нужно будет изменить Cell (я, j). Значение для ячейки (i, j). Формула и избавиться от апостроф перед "= ИНДЕКС", если вы хотите, чтобы ваша формула на самом деле работа.
  • В вашей функции MATCH вы в поисках AH $ 4 & ТЕКСТ ($ B8, "" м / дд / гггг "". Это выглядит немного подозрительно ко мне. Что в сотовый AH $ 4? Выкладывает ли Oracle какой-то странный префикс перед датами? Если у вас просто были простые даты в вашем клетки, вам не нужно беспокоиться о формате (можно избавиться из текста и просто сделать чистый сравнение). Excel хранит даты в виде "серийный номер. Кроме того, проверьте помощь по DATEVALUE. Это может помочь чтобы вы перевели вещи в чистые даты.
  • Просто общее слово совета. Получить ваше выражение MATCH работает в первую очередь. Затем попробуйте вставить матч выражение в выражении INDEX. Это поможет вам изолировать ваши Точная проблема.

Q2. Похоже, у вас уже есть список конвейеров на вашем листе, поэтому вы можете создать проверку, которая гарантирует, что пользователь выберет только допустимый конвейер.

  • Присвойте имя вашему списку трубопроводы. Вы делаете это, выбирая ваш список конвейеров, нажав Определите имя на вкладке "Формулы" лента, затем введите имя.
  • Выберите ячейку на листе для пользователь выбирает конвейер.
  • Нажмите Проверка данных на вкладке Данные ленты.
  • Для Разрешить, выберите Список.
  • В поле Источник введите знак равенства а затем имя, назначенное для Ваш список трубопроводов. Итак, если ваш имя было Трубопроводы, вы бы ввести = Трубопроводы.

Теперь, когда пользователь щелкает эту ячейку, в ней отображаются только конвейеры.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...