如何运行查询,使用VBA宏和Excel自动化,在协调时进行“加载”功能?

时间:2022-11-19 22:07:10

I am building a reconciliation tool via VBA that automates queries from my oracle database and a worksheet. When I run the query I want the user to input what ITEM (in this case pipeline) to query (the worksheet has many items) and the end/start dates. I am having trouble figuring out the following:

我正在通过VBA构建一个协调工具,它可以自动从我的oracle数据库和工作表中查询。当我运行查询时,我希望用户输入要查询的ITEM(在这种情况下是管道)(工作表有很多项)和结束/开始日期。我无法弄清楚以下内容:

1) It is querying - if the value is NULL, how may I tell it to print out "DATA NOT AVAILABLE"
2) How can I clear up the old output from pipeline A, when I am querying pipeline B?
3) My dates are saved as strings in Oracle - how can I convert that to date?
Thank you!

1)正在查询 - 如果值为NULL,我怎么能告诉它打印出“DATA NOT AVAILABLE”2)当我查询管道B时,如何清除管道A的旧输出? 3)我的日期在Oracle中保存为字符串 - 如何将其转换为日期?谢谢!

Here is what I have so far:

这是我到目前为止:

Option Explicit 
Option Base 1

Dim cnnObject As ADODB.Connection
Dim rsObject As ADODB.Recordset
Dim strGPOTSConnectionString As String

Dim startDate As Date
Dim endDate As Date
Dim strPipelineName As String
Dim strQuery As String

Sub ClickButton2()

Debug.Print ("Button has been clicked")
Dim Pipeline As String
Dim DateStart As Date
Dim DateEnd As Date

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)

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

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


    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=hhh; PWD=hhhh; UID=hhh"


cnnObject.Open strGPOTSConnectionString

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()

End Sub

2 个解决方案

#1


Since you changed your questions, I'll add another answer.

由于您更改了问题,我将添加另一个答案。

1) It is querying - if the value is NULL, how may I tell it to print out "DATA NOT AVAILABLE"

1)正在查询 - 如果值为NULL,我怎么告诉它打印出“DATA NOT AVAILABLE”

Which value? I suspect that you mean when the query returns no records. To check this, test for rsObject.RecordCount = 0:

哪个值?我怀疑你的意思是什么时候查询没有返回任何记录。要检查这一点,请测试rsObject.RecordCount = 0:

Dim ws As Worksheet
Set ws = Worksheets("ZaiNet Data")

ws.UsedRange.Clear '' remove results of previous query if any

If rsObject.RecordCount = 0 Then
  ws.Cells(1, 1) = "DATA NOT AVAILABLE"
Else
  ws.Cells(1, 1).CopyFromRecordset rsObject
End If

You can also test for one or both of rsObject.BOF or rsObject.EOF being true ("Beginning Of File" or "End Of File" respectively).

您还可以测试rsObject.BOF或rsObject.EOF中的一个或两个为true(分别为“文件的开头”或“文件的结尾”)。

When developing things in VBA, especially when using new features that I'm unfamiliar with, I do lots of tests that output things to the Immediate Window. To help with this, I use the following little routine:

在VBA中开发内容时,特别是在使用我不熟悉的新功能时,我会做很多测试,将内容输出到立即窗口。为了解决这个问题,我使用了以下小程序:

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

It makes it a little easier to generate testing output that typing "Debug.Print" all the time (even slightly easier than typing "Debug.P" + Enter using Intellisense).

它使得生成一直输入“Debug.Print”的测试输出变得容易一些(甚至比输入“Debug.P”+使用Intellisense输入更容易)。

So when you open your recordset, show the record count after it:

因此,当您打开记录集时,请在其后显示记录计数:

rsObject.Open strQry, cnnObject, adOpenStatic
Say rsObject.RecordCount & " records"

Do something like this any time you want to verify a value.

在您想要验证值时,请执行类似的操作。

Later on, if you want to capture your debugging statements in a text file, you just need to change the operation of the Say() routine.

稍后,如果要在文本文件中捕获调试语句,只需更改Say()例程的操作即可。

2) How can I clear up the old output from pipeline A, when I am querying pipeline B?

2)当我查询管道B时,如何清除管道A的旧输出?

As shown in context above:

如上文所示:

ws.UsedRange.Clear '' remove results of previous query if any

3) My dates are saved as strings in Oracle - how can I convert that to date?

3)我的日期在Oracle中保存为字符串 - 如何将其转换为日期?

You don't technically need to convert the resulting date strings to date values, you may find that just by putting them in a cell, Excel will treat them as date values.

从技术上讲,您不需要将生成的日期字符串转换为日期值,您可能会发现只需将它们放在单元格中,Excel就会将它们视为日期值。

You just need to make sure that the user's dates get converted to the format that the database is expecting.

您只需确保将用户的日期转换为数据库所期望的格式。

Your query string as it stands above still shows two lines incorporating the user's dates. The one that uses Format() to convert them to "dd-MMM-yyyy" format is the one you want to keep. Delete the other line, making sure your string concatenating syntax is still correct.

您上面的查询字符串仍显示包含用户日期的两行。使用Format()将它们转换为“dd-MMM-yyyy”格式的是您要保留的格式。删除另一行,确保字符串连接语法仍然正确。

To actually convert the date string to a date value though, you would use the CDate() function:

要将日期字符串实际转换为日期值,您可以使用CDate()函数:

Sub DateTest()
  Dim sDate As String
  Dim dDate As Date

  sDate = "09-Jul-2009"
  dDate = CDate(sDate)

  Say "sDate = " & sDate
  Say "dDate = " & dDate

  dDate = dDate + 1
  Say "dDate = " & dDate
End Sub


Immediate Window output:
sDate = 09-Jul-2009
dDate = 7/9/2009
dDate = 7/10/2009

We can verify that it converted the string to a date value because it shows up in the default date format for my machine, and responds to date math (adding 1 day).

我们可以验证它是否将字符串转换为日期值,因为它以我的机器的默认日期格式显示,并响应日期数学(添加1天)。

#2


Answers to previous questions (paraphrased):

以前问题的答案(转述):

1) "how to make sure end date is after start date":

1)“如何确保结束日期是在开始日期之后”:

Valid date values are floating point numbers, so DateEnd should be >= DateStart. The whole number part is the number of days since 1900-01-01. The fractional part is the current time of day (eg 12 noon = 0.5).

有效日期值是浮点数,因此DateEnd应为> = DateStart。整数部分是自1900-01-01以来的天数。小数部分是当前时间(例如,中午12点= 0.5)。

2) "use fancy calendar entry controls for dates"

2)“使用日期的花式日历输入控件”

Look at the controls available under the Insert> Object menu (in Excel 2003 and earlier - it's in 2007 too, but in a different place). One of them is a Calendar control. Double-clicking it in the Objects list will insert it into the current cell and put the sheet into Design Mode. Right click the control and choose Properties. Type a cell address into the LinkedCell field. Then click the "Exit Design Mode" button from the little toolbar that should have popped up. Now when you select a date on the control, it will show the value in the cell you linked it to.

查看“插入”>“对象”菜单下的可用控件(在Excel 2003及更早版本中 - 它也在2007年,但在不同的位置)。其中一个是Calendar控件。在“对象”列表中双击它会将其插入当前单元格并将工作表置于“设计模式”中。右键单击该控件并选择“属性”。在LinkedCell字段中键入单元格地址。然后单击应弹出的小工具栏上的“退出设计模式”按钮。现在,当您在控件上选择日期时,它将在您将其链接到的单元格中显示该值。

Similarly there is a drop down list control that you can use to select your pipeline types.

类似地,有一个下拉列表控件,您可以使用它来选择管道类型。

3) "why am I getting an error on DateEnd = Range("B3").Value?"

3)“为什么我在DateEnd = Range(”B3“)上收到错误。值?”

The DateEnd error is probably due to a missing or invalid value in the cell you specified, as I asked in my comment.

DateEnd错误可能是由于我指定的单元格中的值丢失或无效,正如我在评论中提到的那样。

What version of Excel are you doing this in? Excel 2003

你在做什么版本的Excel? Excel 2003

#1


Since you changed your questions, I'll add another answer.

由于您更改了问题,我将添加另一个答案。

1) It is querying - if the value is NULL, how may I tell it to print out "DATA NOT AVAILABLE"

1)正在查询 - 如果值为NULL,我怎么告诉它打印出“DATA NOT AVAILABLE”

Which value? I suspect that you mean when the query returns no records. To check this, test for rsObject.RecordCount = 0:

哪个值?我怀疑你的意思是什么时候查询没有返回任何记录。要检查这一点,请测试rsObject.RecordCount = 0:

Dim ws As Worksheet
Set ws = Worksheets("ZaiNet Data")

ws.UsedRange.Clear '' remove results of previous query if any

If rsObject.RecordCount = 0 Then
  ws.Cells(1, 1) = "DATA NOT AVAILABLE"
Else
  ws.Cells(1, 1).CopyFromRecordset rsObject
End If

You can also test for one or both of rsObject.BOF or rsObject.EOF being true ("Beginning Of File" or "End Of File" respectively).

您还可以测试rsObject.BOF或rsObject.EOF中的一个或两个为true(分别为“文件的开头”或“文件的结尾”)。

When developing things in VBA, especially when using new features that I'm unfamiliar with, I do lots of tests that output things to the Immediate Window. To help with this, I use the following little routine:

在VBA中开发内容时,特别是在使用我不熟悉的新功能时,我会做很多测试,将内容输出到立即窗口。为了解决这个问题,我使用了以下小程序:

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

It makes it a little easier to generate testing output that typing "Debug.Print" all the time (even slightly easier than typing "Debug.P" + Enter using Intellisense).

它使得生成一直输入“Debug.Print”的测试输出变得容易一些(甚至比输入“Debug.P”+使用Intellisense输入更容易)。

So when you open your recordset, show the record count after it:

因此,当您打开记录集时,请在其后显示记录计数:

rsObject.Open strQry, cnnObject, adOpenStatic
Say rsObject.RecordCount & " records"

Do something like this any time you want to verify a value.

在您想要验证值时,请执行类似的操作。

Later on, if you want to capture your debugging statements in a text file, you just need to change the operation of the Say() routine.

稍后,如果要在文本文件中捕获调试语句,只需更改Say()例程的操作即可。

2) How can I clear up the old output from pipeline A, when I am querying pipeline B?

2)当我查询管道B时,如何清除管道A的旧输出?

As shown in context above:

如上文所示:

ws.UsedRange.Clear '' remove results of previous query if any

3) My dates are saved as strings in Oracle - how can I convert that to date?

3)我的日期在Oracle中保存为字符串 - 如何将其转换为日期?

You don't technically need to convert the resulting date strings to date values, you may find that just by putting them in a cell, Excel will treat them as date values.

从技术上讲,您不需要将生成的日期字符串转换为日期值,您可能会发现只需将它们放在单元格中,Excel就会将它们视为日期值。

You just need to make sure that the user's dates get converted to the format that the database is expecting.

您只需确保将用户的日期转换为数据库所期望的格式。

Your query string as it stands above still shows two lines incorporating the user's dates. The one that uses Format() to convert them to "dd-MMM-yyyy" format is the one you want to keep. Delete the other line, making sure your string concatenating syntax is still correct.

您上面的查询字符串仍显示包含用户日期的两行。使用Format()将它们转换为“dd-MMM-yyyy”格式的是您要保留的格式。删除另一行,确保字符串连接语法仍然正确。

To actually convert the date string to a date value though, you would use the CDate() function:

要将日期字符串实际转换为日期值,您可以使用CDate()函数:

Sub DateTest()
  Dim sDate As String
  Dim dDate As Date

  sDate = "09-Jul-2009"
  dDate = CDate(sDate)

  Say "sDate = " & sDate
  Say "dDate = " & dDate

  dDate = dDate + 1
  Say "dDate = " & dDate
End Sub


Immediate Window output:
sDate = 09-Jul-2009
dDate = 7/9/2009
dDate = 7/10/2009

We can verify that it converted the string to a date value because it shows up in the default date format for my machine, and responds to date math (adding 1 day).

我们可以验证它是否将字符串转换为日期值,因为它以我的机器的默认日期格式显示,并响应日期数学(添加1天)。

#2


Answers to previous questions (paraphrased):

以前问题的答案(转述):

1) "how to make sure end date is after start date":

1)“如何确保结束日期是在开始日期之后”:

Valid date values are floating point numbers, so DateEnd should be >= DateStart. The whole number part is the number of days since 1900-01-01. The fractional part is the current time of day (eg 12 noon = 0.5).

有效日期值是浮点数,因此DateEnd应为> = DateStart。整数部分是自1900-01-01以来的天数。小数部分是当前时间(例如,中午12点= 0.5)。

2) "use fancy calendar entry controls for dates"

2)“使用日期的花式日历输入控件”

Look at the controls available under the Insert> Object menu (in Excel 2003 and earlier - it's in 2007 too, but in a different place). One of them is a Calendar control. Double-clicking it in the Objects list will insert it into the current cell and put the sheet into Design Mode. Right click the control and choose Properties. Type a cell address into the LinkedCell field. Then click the "Exit Design Mode" button from the little toolbar that should have popped up. Now when you select a date on the control, it will show the value in the cell you linked it to.

查看“插入”>“对象”菜单下的可用控件(在Excel 2003及更早版本中 - 它也在2007年,但在不同的位置)。其中一个是Calendar控件。在“对象”列表中双击它会将其插入当前单元格并将工作表置于“设计模式”中。右键单击该控件并选择“属性”。在LinkedCell字段中键入单元格地址。然后单击应弹出的小工具栏上的“退出设计模式”按钮。现在,当您在控件上选择日期时,它将在您将其链接到的单元格中显示该值。

Similarly there is a drop down list control that you can use to select your pipeline types.

类似地,有一个下拉列表控件,您可以使用它来选择管道类型。

3) "why am I getting an error on DateEnd = Range("B3").Value?"

3)“为什么我在DateEnd = Range(”B3“)上收到错误。值?”

The DateEnd error is probably due to a missing or invalid value in the cell you specified, as I asked in my comment.

DateEnd错误可能是由于我指定的单元格中的值丢失或无效,正如我在评论中提到的那样。

What version of Excel are you doing this in? Excel 2003

你在做什么版本的Excel? Excel 2003