Считать файл CSV / Excel в массив - PullRequest
0 голосов
/ 30 августа 2018

Я пытаюсь создать макрос, который копирует электронные письма при их получении и сохраняет их в определенных папках Windows на сетевом диске в зависимости от имени домена.

Список доменов, которые у меня есть, будет большим и может изменяться пользователями без опыта написания кода, поэтому я хочу разработать текстовый, CSV-файл или файл Excel, который кто-то может обновить, в котором перечислены отношения моей компании к ним (клиент, поставщик, субподрядчик и т. д.) и их имя (оба из которых управляют путем к файлу), имя домена (@ example.com).

Я думаю, что могу выяснить, как сделать большую часть этого (умная комбинация вложенных операторов if и for), но я не могу понять, как прочитать файл в массив, и мой google-fu не удался я.

Не думаю, что это действительно помогает, но вот код, который я беззастенчиво скопировал из Интернета и планирую отработать.

Option Explicit
Private WithEvents InboxItems As Outlook.Items

Sub Application_Startup()
    Dim xNameSpace As Outlook.NameSpace
    Set xNameSpace = Outlook.Application.Session
    Set InboxItems = xNameSpace.GetDefaultFolder(olFolderInbox).Items
End Sub

Private Sub InboxItems_ItemAdd(ByVal objItem As Object)
    Dim FSO
    Dim xMailItem As Outlook.MailItem
    Dim xFilePath As String
    Dim xRegEx
    Dim xFileName As String
    Dim SenderAddress As String
    On Error Resume Next

    ' Define SenderAddress as sender's email address or domain
    xFilePath = PathCreator(SenderAddress)

    Set FSO = CreateObject("Scripting.FileSystemObject")
    If FSO.FolderExists(xFilePath) = False Then
        FSO.CreateFolder (xFilePath)

    End If

    Set xRegEx = CreateObject("vbscript.regexp")
    xRegEx.Global = True
    xRegEx.IgnoreCase = False
    xRegEx.Pattern = "\||\/|\<|\>|""|:|\*|\\|\?"

    If objItem.Class = olMail Then
        Set xMailItem = objItem
        xFileName = xRegEx.Replace(xMailItem.Subject, "")
        xMailItem.SaveAs xFilePath & "\" & xFileName & ".html", olHTML

    End If
    Exit Sub

End Sub

Function PathCreator(SenderAddress)

' [needs to read the file and create the path based on the values]

End Function

1 Ответ

0 голосов
/ 31 августа 2018

Вы можете использовать ADODB для подключения к исходному файлу и считывания его в двумерный массив. Добавьте ссылку на объекты данных Microsoft ActiveX из Инструменты -> Ссылки ... . Например, если вы хотите использовать файл Excel:

Dim excelPath As String
excelPath = "C:\path\to\excel\file.xlsx" ' Replace with the path to the Excel file

Dim connectionString As String
connectionString = _
    "Provider=Microsoft.ACE.OLEDB.12.0;" & _
    "Data Source=""" & excelPath & """;" & _
    "Extended Properties=""Excel 12.0;HDR=Yes"""
'This assumes the Excel file contains column headers -- HDR=Yes

Dim sql As String
sql = "SELECT Relationship, LastName, FirstName, DomainName FROM [Sheet1$]"
'Assumes the relevant worksheet is named Sheet1
'Also assumes the first row of the sheet has the following labels: Relationship, LastName, FirstName, Domain (in no particular order)

Dim rs As New ADODB.Recordset
rs.Open sql, connectionString

Dim arr As Variant
arr = rs.GetRows 'Puts the data from the recordset into an array
rs.Close 
Set rs = Nothing

Dim row As Variant, column As Variant
For row = 0 To UBound(arr, 2)
    For column = 0 To UBound(arr, 1)
        Debug.Print arr(column, row)
    Next
Next

Использование текстового файла или CSV - это всего лишь вопрос небольшого изменения строки подключения и SQL. Но я думаю, что использование файла Excel заставит пользователей хранить данные в столбцах, где в CSV пользователи должны будут вставлять разделители полей и строк вручную; то же самое для любого другого текстового формата - пользователи должны будут помнить правила формата и применять их правильно.


Но я спрашиваю, является ли массив лучшей структурой данных для вас; в этом случае вы можете использовать набор записей напрямую. Чтобы убедиться, что файл не остается открытым, вы можете использовать отключенный набор записей. (Если вы намереваетесь найти подходящее доменное имя и использовать его для получения других сведений, я бы предложил вам загрузить данные из набора записей в Scripting.Dictionary.)

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

Я бы написал что-то вроде этого

Dim rs As ADODB.Recordset

Function PathCreator(SenderAddress) As String
    If rs Is Nothing Then
        Dim excelPath As String
        excelPath = "C:\path\to\excel\file.xlsx" ' Replace with the path to the Excel file

        Dim connectionString As String
        connectionString = _
            "Provider=Microsoft.ACE.OLEDB.12.0;" & _
            "Data Source=""" & excelPath & """;" & _
            "Extended Properties=""Excel 12.0;HDR=Yes"""

        Dim sql As String
        sql = "SELECT Relationship, LastName, FirstName, DomainName FROM [Sheet1$]"

        Set rs As New ADODB.Recordset
        rs.CursorLocation = adUseClient
        rs.CursorType = adOpenStatic
        rs.Open sql, connectionString, adOpenStatic, adLockBatchOptimistic

        'Disconnect the recordset
        rs.ActiveConnection = Nothing

        'Now the data will still be available as long as the code is running
        'But the connection to the Excel file will be closed
    End If

    'build the path here, using the recordset fields
    PathCreator = rs!Relationship & "_" & rs!LastName & "_" & rs!FirstName & "_" & rs!Domain
End Function

NB. Точно так же вы можете добавить ссылку на Microsoft Scripting Runtime ; Затем вы можете написать код, который использует FileSystemObject следующим образом:

Dim FSO As New Scripting.FileSystemObject
If Not FSO.FolderExists(xFilePath) Then
    FSO.CreateFolder xFilePath

End If

и со ссылкой на Регулярные выражения Microsoft VBScript 5.5 libary:

Set xRegEx As New VBScript_RegExp_55.RegExp
xRegEx.Global = True
xRegEx.IgnoreCase = False
xRegEx.Pattern = "\||\/|\<|\>|""|:|\*|\\|\?"

If objItem.Class = olMail Then
    Set xMailItem = objItem
    xFileName = xRegEx.Replace(xMailItem.Subject, "")
    xMailItem.SaveAs xFilePath & "\" & xFileName & ".html", olHTML

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