如何在Excel宏中传递模块之间的连接参数

mjqavswn  于 2023-05-08  发布在  其他
关注(0)|答案(3)|浏览(269)

我使用Excel宏在一个工作表中创建两个报告。报告连接到Oracle DB以提取数据。拉取数据的连接字符串起作用。
我尝试将连接字符串移动到一个函数中,并根据用户输入将其传递到相应的报表。
高液位流量:
1.用户单击菜单按钮。在后台,它尝试连接到DB。
1.如果连接成功,它会打开一个带有按钮A和按钮B的表单(用户希望运行哪个报告)。
1.假设用户单击按钮A,则应执行并显示报告。
问题出现在步骤2中。我无法将连接参数传递给按钮A函数。
连接到DB的代码。

Dim dbConnect As ADODB.Connection
Dim GetData As ADODB.Recordset

'Declare a set of variables to hold the username and password for the database
Dim strUserName As String
Dim strPassword As String
Dim strDatabase As String
Set GetData = New ADODB.Recordset
'***

On Error Resume Next

Set dbConnect = New ADODB.Connection

dbConnect.Open ( _
  "User ID=" & strUserName & "; Password=" & strPassword & "; Data Source=" & strDatabase & "; Provider=msdaora")
 
'If the username or password is incorrect throw an error message
If (dbConnect.State <> 1) Or (Err <> 0) Then
    intResult = MsgBox("Could not connect to the database.  Check your user name and password." & vbCrLf & Error(Err), 16, " ")
Else
    '.ConnectionString = dbConnect
    ReportGenerator.Show ' this opens up another form where 
                         '  user can input the dates.
                         'This is turn calls the actual code...
End If

End Sub

在报告生成器窗体中,将日期参数传递给函数

Private Sub Login_Click()
    Call ReportGenerator(FromDate.Value, ToDate.Value)
End Sub

我需要将连接参数传递给CallReportGenerator函数。

yyyllmsg

yyyllmsg1#

有多个是你可以这样做:

选项一:使用全局变量

如果在模块的顶部声明一个变量为Global,即在任何subs/函数之前,你可以从任何其他模块访问它们:
示例-模块1:

Option Explicit

Global gStrConnection As String 'g for Global scope

Sub Connect()
    gStrConnection = "User ID=" & strUserName & "; Password=" & strPassword & "; Data Source=" & strDatabase & "; Provider=msdaora")    
   dbConnect.Open gStrConnection
   ...
End Sub

形式:

Private Sub CreateReport()
    dbConnect.Open gStrConnection
    ...
End Sub

选项二:将变量传递给本地表单变量

在Form的模块中声明一个模块范围的变量(即在哪里放置表单的其他代码)。然后提供一个小的setter子程序来赋值。
示例-模块1:

Option Explicit

Sub Connect()
    Dim strConnection as String
    strConnection = "User ID=" & strUserName & "; Password=" & strPassword & "; Data Source=" & strDatabase & "; Provider=msdaora")    
   dbConnect.Open strConnection
   ...
    ReportGenerator.StoreConnectionString strConnection
    ReportGenerator.Show
    ...
End Sub

形式:

Private mStrConnection as String 'm for module-wide scope

Public Sub StoreConnectionString(strConnection as String)
    mStrConnection = strconnection
End Sub

Private Sub CreateReport()
    dbConnect.Open mStrConnection
    ...
    ...
End Sub
zsbz8rwp

zsbz8rwp2#

在标准模块的顶部声明连接和记录集,在任何过程之外,并将它们的访问器设置为public。
记得在完成后清理资源。

xxls0lw8

xxls0lw83#

当我在研究Peter Albert的选项1时,我想到了另一种方法。我需要有一个地方来存储连接字符串,可以在开发,测试和生产环境之间进行修改,以连接到Azure SQL数据库。我采用的方法将字符串声明为Global(gconn),并在该模块(connectDB,在示例中不可见)中定义字符串,然后调用该模块的Connect Sub过程来获取全局字符串变量。这使我可以在一个单独的模块中简单地定义连接字符串,并在执行sql的子过程中执行所有连接的打开和关闭。我不想在当前模块之外执行任何打开和关闭子过程。

Option Explicit

Sub testconnection()
Dim cn As New ADODB.Connection
Call Connect
cn.Open gconn
cn.Close

注意,我在connectDB模块中所做的只是声明Global字符串。

Option Explicit

Global gconn As String

Sub Connect()
gconn = "Provider=MSOLEDBSQL19;" & _
     "Data Source=AzureSQLDatabaseAddress;" & _
     "Initial Catalog=DatabaseName;" & _
     "User ID=SomeUser;" & _
     "Password=SomePassword;" & _
     "Use Encryption for Data=False;" & _
     "DataTypeCompatibility=80"

End Sub

这是我在Stack Overflow中的第一个答案,请对我宽容一些:)。我想在写了将近20年的SQL和VBA之后,我应该在这里贡献一点。

相关问题