Vba 通过代码更改连接字符串

Vba 通过代码更改连接字符串,vba,excel,connection-string,Vba,Excel,Connection String,我有9张工作表连接到teradata中的不同表,每次我都必须输入用户名和密码才能刷新和获取新的数据集。有人能告诉我如何编写一个VBA代码,可以更改每个连接的连接字符串并刷新数据表。我是VBA的一名内部人员,不知道如何在VBA中编码 谢谢 Syam以下是我要做的:我将以下内容放在单元格A2:B5中 数据来源: 数据库: 我把SQL放在D2单元格中。我使用第1行来告诉我查询需要多长时间。然后,我在页面的任意位置添加一个按钮。然后我调用下面的代码。它看起来很复杂,但功能的核心是Get_Data_Ter

我有9张工作表连接到teradata中的不同表,每次我都必须输入用户名和密码才能刷新和获取新的数据集。有人能告诉我如何编写一个VBA代码,可以更改每个连接的连接字符串并刷新数据表。我是VBA的一名内部人员,不知道如何在VBA中编码

谢谢
Syam

以下是我要做的:我将以下内容放在单元格A2:B5中 数据来源: 数据库: 我把SQL放在D2单元格中。我使用第1行来告诉我查询需要多长时间。然后,我在页面的任意位置添加一个按钮。然后我调用下面的代码。它看起来很复杂,但功能的核心是Get_Data_Teradata

Get_SQL函数只需向下读取D列,直到找到一个空行,然后为SQL返回一大块文本。您可以用硬编码的SQL语句替换它

Pop_Col_Heads将结果中的列标题放入第1行。请注意,我在Win 7上的Excel 2010中发现了一个Bug,在该Bug中,我只能在每个Excel会话中填充一到两次列。如果我退出并再次加载Excel,它会再次工作一两次

从RDBMS复制数据将ADODB记录集放入活动工作表中的某个范围。我不得不做一些调整来处理插入和更新,因为它们不返回任何行

Sub Get_Data_Teradata()
'Supports Multi Query
Dim cn As ADODB.Connection
    Dim sConnect As String
    Set cn = New ADODB.Connection
    Dim rs As ADODB.Recordset
    Set rs = New ADODB.Recordset
    Dim cmdSQLData As ADODB.Command
    Set cmdSQLData = New ADODB.Command
    Dim sQueries() As String

    sConnect = "Persist Security Info=True; Session Mode=ANSI; " & _
               "Data Source=" & ActiveSheet.Range("B2").Value & ";" & _
               "Database=" & ActiveSheet.Range("B3").Value & ";" & _
               "User ID=" & ActiveSheet.Range("B4").Value & ";" & _
               "Password=" & ActiveSheet.Range("B5").Value & ";"
    sQueries = Get_SQL(ActiveSheet.Range("D2:D9999"))
    nRow = 1 'initialize to start at the top of the page
    For i = 0 To UBound(sQueries) - 1
        cn.Open sConnect
        Set cmdSQLData.ActiveConnection = cn
        cmdSQLData.CommandText = sQueries(i) 'TELL VBA TO LOAD THE QUERY INTO TERADATA
        cmdSQLData.CommandType = adCmdText
        cmdSQLData.CommandTimeout = 0
        Set rs = cmdSQLData.Execute()
        Call Pop_Col_Heads(rs, nRow)
        nRow = Copy_Data_From_RDBMS(rs, nRow)
        cn.Close
    Next i
End Sub

Dim a As Long
Dim i As Long
Dim nIndex As Long
Dim sSQL() As String


Function Get_SQL(oRange As Object) As String()
'First figure out how many rows the SQL statement is
a = 0
    For Each cCell In oRange
        a = a + 1
        If cCell.Value = "" Then
            a = a - 1
            Exit For
        End If
    Next cCell

'Num rows = a now
'Step through and parse into array
    i = 0
    nIndex = 0
    ReDim Preserve sSQL(1)
    For Each cCell In oRange
        i = i + 1
        If i > a Then
            Exit For
        ElseIf cCell.Value = "<Multi>" Then
            nIndex = nIndex + 1
            ReDim Preserve sSQL(nIndex + 1)
        Else
            sSQL(nIndex) = sSQL(nIndex) & To_Text(cCell.Value) & " "
        End If
    Next cCell
    Get_SQL = sSQL
End Function

Sub Pop_Col_Heads(rs As Object, nRow As Long)
    Dim rHeads As Range
    Dim fFields As Field
    Dim nCol As Integer

    nCol = 0
    If nRow = 1 Then
        ActiveSheet.Range("E1:ZZ1").ClearContents
    End If
    Set rHeads = ActiveSheet.Range("E1").Offset(nRow - 1, 0)
    Do While nCol < rs.Fields.Count
        sTemp = rs.Fields(nCol).Name
        rHeads.Cells(nRow, nCol + 1).Value = rs.Fields(nCol).Name
        ActiveSheet.Calculate
        rHeads.Cells(nRow, nCol + 1).Value = sTemp
        nCol = nCol + 1
        rHeads.WrapText = True
        rHeads.VerticalAlignment = xlVAlignTop
    Loop
End Sub

Function Copy_Data_From_RDBMS(rs As Object, nRow As Long) As Long
'Supports Multi Query
    If nRow = 1 Then
        x = Get_Last_Row_Find(ActiveSheet.Range("E1:ZZ64000"))
        ActiveSheet.Range("E2:ZZ" & x).ClearContents
    End If
    On Error Resume Next
    rs.MoveFirst
    On Error GoTo 0
    If Not rs.EOF Then
        ActiveSheet.Range("E2").Offset(nRow - 1, 0).CopyFromRecordset rs
        x = Get_Last_Row_Find(ActiveSheet.Range("E1:ZZ64000"))
        Copy_Data_From_RDBMS = x + 1
        ActiveSheet.Range("E2:ZZ" & x).Offset(nRow - 1, 0).WrapText = False
    Else 'no results (e.g. insert)
        ActiveSheet.Range("E2").Offset(nRow - 1, 0).Value = "<no data returned>"
    End If
    rs.Close
    Set rs = Nothing
End Function
Sub Get_Data_Teradata()
'支持多查询
Dim cn作为ADODB.Connection
暗连接为字符串
Set cn=New ADODB.Connection
将rs设置为ADODB.Recordset
Set rs=New ADODB.Recordset
Dim cmdSQLData作为ADODB.Command
Set cmdSQLData=New ADODB.Command
Dim sQueries()作为字符串
sConnect=“Persist Security Info=True;会话模式=ANSI;”_
“数据源=”&ActiveSheet.Range(“B2”).Value&“;”&”_
“Database=“&ActiveSheet.Range(“B3”).值&“;”&”_
“用户ID=”&ActiveSheet.Range(“B4”).Value&“;”&”_
“Password=“&ActiveSheet.Range(“B5”).Value&;”
sQueries=Get_SQL(ActiveSheet.Range(“D2:D9999”))
nRow=1'初始化为从页面顶部开始
对于i=0到UBound(sQueries)-1
开放式连接
设置cmdSQLData.ActiveConnection=cn
cmdSQLData.CommandText=sQueries(i)'告诉VBA将查询加载到TERADATA中
cmdSQLData.CommandType=adCmdText
cmdSQLData.CommandTimeout=0
设置rs=cmdSQLData.Execute()
呼叫Pop_colu___头
nRow=从RDBMS复制数据(rs,nRow)
cn.Close
接下来我
端接头
暗淡如长
我想我会坚持多久
暗九倍长
Dim sSQL()作为字符串
函数Get_SQL(橙色作为对象)作为字符串()
'首先计算SQL语句的行数
a=0
对于橙色的每个cCell
a=a+1
如果cCell.Value=”“,则
a=a-1
退出
如果结束
下一个cCell
'Num rows=a now
'单步执行并解析为数组
i=0
nIndex=0
ReDim保留sSQL(1)
对于橙色的每个cCell
i=i+1
如果我>a那么
退出
ElseIf cCell.Value=”“然后
nIndex=nIndex+1
ReDim保留sSQL(nIndex+1)
其他的
sSQL(nIndex)=sSQL(nIndex)和To_Text(cCell.Value)和“”
如果结束
下一个cCell
Get_SQL=sSQL
端函数
子Pop_colu___头(rs作为对象,nRow作为长度)
暗rHeads As射程
暗场
作为整数的Dim-nCol
nCol=0
如果nRow=1,则
ActiveSheet.Range(“E1:ZZ1”).ClearContents
如果结束
设置rHeads=ActiveSheet.Range(“E1”).偏移量(nRow-1,0)
当nCol
如何检索数据?通过VBA宏或其他方法?尝试在刷新数据时录制宏,然后使用此宏(附加到工作表中某个按钮上的单击)或其修改版本,在将来需要刷新数据时更新连接。当您想学习如何在excel/vba中自动化几乎所有内容时,这种方法就可以工作了(因为您可以解析记录的宏,以查看Microsoft如何在代码中执行任务)。Hi Shiva,我正在通过ODBC连接获取数据。Tanks尝试过这种方法,并为我工作过。