Изменить строку подключения Excel с помощью VB .NET

Наш файл Excel использует внешние данные для связи с нашим сервером базы данных. Недавно наша компания изменила и перенесла наш сервер базы данных на новый сервер.

Все файлы Excel не удалось подключиться к базе данных из-за отсутствия старого имени сервера. Поэтому мне нужно открыть файл excel и изменить имя сервера строки подключения со старого на новое. Но есть более сотни Excel, которым нужно изменить строку подключения, поэтому я начинаю думать об использовании VB .NET для создания программы для массового изменения строки подключения Excel.

Это возможно? Это может сэкономить мое время, чтобы изменить файл Excel один за другим.

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
0
500
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Это довольно распространено, и существует существующий код, который вы сможете изменить в соответствии со своими потребностями:

Кстати, вы будете использовать Excel VBA, а не VB .Net.

Private Sub Workbook_Open()

Dim conn As WorkbookConnection
Dim sOldConnection As String, sNewConnection As String
Dim sOldPath As String
Dim sNewPath As String
Dim sLength As Integer
Dim sOldPath1 As String
Dim intDsnLen As Integer
Dim intDsnStart As Integer
Dim intDsnEnd As Integer

'I first check if there is a folder called "Analysis" as this is what we generally use to store our analysis tools.
If InStr(1, Application.ThisWorkbook.Path, "Analysis") > 0 Then
'I then remove that from the path that I require
sLength = Len(Application.ThisWorkbook.Path) - 9
'I set the new path to the workbook path minus the analysis folder and the "\"
sNewPath = Left(Application.ThisWorkbook.Path, sLength)
Else
'If the folder doesn't exist, I then set the new part to the excel workbooks path
sLength = Len(Application.ThisWorkbook.Path)
sNewPath = Left(Application.ThisWorkbook.Path, sLength)
End If

For Each conn In ActiveWorkbook.Connections
With conn
If .Type = xlConnectionTypeODBC Then
sOldConnection = .ODBCConnection.Connection

'I used these steps to find my specific connection string....not the best way to use it but I was getting
'a bit irritated with the fact that instr doesn't remove all that I don't require.
'In my case, this will always work...may not for others but you can always play around to find your best fit.
intDsnStart = InStr(1, sOldConnection, "DBQ") + 3
intDsnEnd = InStr(intDsnStart, sOldConnection, "Reports.MDB")
intDsnLen = intDsnEnd - intDsnStart
'I get my old path in my old connection..I need this specifically as I want to replace it
sOldPath = Mid(sOldConnection, intDsnStart + 1, intDsnLen - 2)

'Here, I replace the old path with the new path, irrespective of whether it is the same or not in my new connection
sNewConnection = Replace(sOldConnection, _
sOldPath, sNewPath, Compare:=vbTextCompare)
'I set the odbc connection to my new built connection and then refresh
.ODBCConnection.Connection = sNewConnection
.Refresh

End If
End With
Next conn

Set conn = Nothing

Код взят отсюда:

Форум Excel

FWIW. Если OP хочет написать приложение Visual Studio, то это VB.net, а не VBA. Поскольку OP также пометил его как C#, я бы предположил, что OP хочет приложение VS. В противном случае ваш код в порядке, если OP доволен использованием модуля Excel.

Automate This 14.12.2020 03:14
Ответ принят как подходящий

Мне нужно поблагодарить @GoodJuJu за совет использовать Excel VBA. Но функция не очень мне нужна.

Поэтому я потратил 1 день на исследования, чтобы создать собственную функцию.

Эта функция может заменить всю строку подключения Excel в папке и подпапках.

Ниже кода я скопировал функцию папки поиска с веб-сайта ExcelOffTheGrid

Просто измените «targetName» и «cvtFrom» и «cvtTo» в функции connStrReplacer(). Пример: моему соединению нужно изменить «ServerName» с SERVER01 на SERVER02. Итак, targetName = "ServerName", cvtFrom = "SERVER01.1583", cvtTo = "SERVER02.1583".

Надеюсь, это может помочь другим, которым также нужна такая функция.

DSN=GLOBAL_TST;ServerName=SERVER01.1583;UID=Master;ArrayFetchOn=1;ArrayBufferSize=8;TransportHint=TCP:SPX;DBQ=GLOBALTST;ClientVersion=12.11.025.000;CodePageConvert=1252;PvClientEncoding=CP1252;PvServerEncoding=CP12 52; AutoDoubleQuote=0;

    Public count As Integer
    
    'Copied Source from https://exceloffthegrid.com/vba-code-loop-files-folder-sub-folders/
    Sub loopAllSubFolderSelectStartDirectory()
        
        Dim FSOLibrary As FileSystemObject
        Dim FSOFolder As Object
        Dim folderName As String
        
        count = 3
                
        With Sheet1
        
            'Delete the old record in Sheet1
            .Range("A:D").Delete
        
            'Set header of record
            .Range("A" & count).Value = "Matched"
            .Range("B" & count).Value = "Replaced"
            .Range("C" & count).Value = "Connection"
            .Range("D" & count).Value = "File Path"
            
            'Set format & style
            .Range("A:C").HorizontalAlignment = xlCenter
            .Range("A:C").Columns.AutoFit
            
        End With
            
        'Set the folder name to a variable
        folderName = ActiveWorkbook.Path
        
        'Set the reference to the FSO Library
        Set FSOLibrary = New FileSystemObject
                
        'Another Macro must call LoopAllSubFolders Macro to start
        LoopAllSubFolders FSOLibrary.GetFolder(folderName)
        
        MsgBox ("Finished!")
        
    End Sub
    
    'Copied Source from https://exceloffthegrid.com/vba-code-loop-files-folder-sub-folders/
    Sub LoopAllSubFolders(FSOFolder As Object)
    
        Dim FSOSubFolder As Object
        Dim FSOFile As Object
        Dim fso As Object
        
        Set fso = CreateObject("Scripting.FileSystemObject")
        
        'For each subfolder call the macro
        For Each FSOSubFolder In FSOFolder.SubFolders
            LoopAllSubFolders FSOSubFolder
        Next
        
        'For each file, print the name
        For Each FSOFile In FSOFolder.Files
        
            'Insert the actions to be performed on each file
            'This example will print the full file path to the immediate window
            Dim ext As String
            ext = fso.GetExtensionName(FSOFile.Path)
            
            'Match extension with the excel file
            'Skip for hidden excel file -> Left(FSOFile.Name, 1) <> "~"
            If (ext = "xlsm" Or ext = "xlsx" Or ext = "xls") And Left(FSOFile.Name, 1) <> "~" Then
                
                'Call function and pass excel filename with path
                connStrReplacer (FSOFile.Path)
                
            End If
            
        Next
    
    End Sub
    Sub connStrReplacer(fileName As String)
        
        Dim newWB, actWB As Workbook
        Dim conn As WorkbookConnection
        Dim targetName, cvtTo As String
        Dim cvtFrom, status As Variant
        
        'The name in the connection string
        targetName = "ServerName"
        
        'Matching the list of value for the target name
        cvtFrom = Array("HFBE-DC01-SVR.1583", "192.168.0.4.1583")
        
        'Replace to this value if the value is matched with above list
        cvtTo = "HFBE-GSS01-VM.1583"
        
        'declare Active Workbook
        Set actWB = ActiveWorkbook
        
        'Skip if is same excel with the current excel
        If fileName = (actWB.Path & "\" & actWB.Name) Then Exit Sub
        
        'Record the result to Sheet1
        count = count + 1
        
        With Sheet1
            .Range("A" & count).Value = "?"
            .Range("B" & count).Value = "?"
            .Range("C" & count).Value = "?"
            .Range("D" & count).Value = fileName
        End With
        
        With Application
            .Calculation = xlCalculationManual
            .ScreenUpdating = False
            .EnableEvents = False
        End With
        
        'Skip if cannot open excel (Exp: excel is protected)
        On Error Resume Next
        'Open file if is an excel file
        Set newWB = Workbooks.Open(fileName, False, False, , "")
        On Error GoTo 0
        
        'newWB is empty mean cannot open excel
        If IsEmpty(newWB) Then
        
            status = Array("Cannot Open Excel", "", "")
        
        Else
        
            Dim countConn, countRplc, countMatch As Integer
            countConn = 0
            countRplc = 0
            countMatch = 0
            
            'Loop for all connection in the opened workbook
            For Each conn In newWB.Connections
            
                'Check connection type if is Database Query
                If conn.Type = 2 Then
                
                    countConn = countConn + 1
                    With conn.ODBCConnection
                        
                        Dim newConStr As String
                        Dim conStr, item, item2 As Variant
                        Dim matched As Boolean
                        
                        newConStr = ""
                        matched = False
                        
                        'Split the connection to each part
                        conStr = Split(.Connection, ";")
                        
                        For Each item In conStr
                            
                            'Do nothing if item is nothing
                            If item = "" Then
                                
                            'Check connection string if has no " = " sign
                            ElseIf InStr(item, " = ") = 0 Then
                                
                                'Setting back the value to New Connection String
                                newConStr = newConStr & item & ";"
                                
                            Else
                            
                                Dim text As Variant
                                Dim newStr As String
                                
                                'Setting default value
                                newStr = item & ";"
                                
                                'Split if " = " is found
                                text = Split(item, " = ")
                                
                                'Matching the value name with the target name
                                If text(0) = targetName Then
                                    countMatch = countMatch + 1
                                    'Matching the value with the value list
                                    For Each item2 In cvtFrom
                                        'If matched then replace with new value
                                        If text(1) = item2 Then
                                            newStr = targetName & " = " & cvtTo & ";"
                                            matched = True
                                        End If
                                    Next
                                End If
                                
                                'Set the string part into the new connection string
                                newConStr = newConStr & newStr
                                
                            End If
                            
                        Next
                        
                        If matched Then
                            Dim dflt As Boolean
                            dflt = .EnableRefresh
                            .EnableRefresh = True
                            'Replace the old connection string to new
                            .Connection = newConStr
                            .EnableRefresh = dflt
                            countRplc = countRplc + 1
                        End If
                        
                    End With
                    
                End If
                
            Next conn
        
            If countConn = 0 Then
                status = Array("0", "0", "0")
            Else
                status = Array(countMatch, countRplc, countConn)
            End If
            
            Application.DisplayAlerts = False
            newWB.Save
            newWB.Close
        
        End If
        
        With Application
            .Calculation = xlAutomatic
            .ScreenUpdating = True
            .EnableEvents = True
            .DisplayAlerts = True
        End With
        
        With Sheet1
            .Range("A" & count).Value2 = status(0)
            .Range("B" & count).Value2 = status(1)
            .Range("C" & count).Value2 = status(2)
            .Range("D" & count).Select
        End With
        
    End Sub

Другие вопросы по теме