Изменение пути к внешнему источнику данных сводной таблицы с помощью макроса Excel

Я работаю над проектом в MS Excel, где у меня есть несколько сводных таблиц, которые считывают данные из текстового файла с разделителями табуляции с именами столбцов в первой строке (в том же каталоге, что и файл Excel) с помощью текстового драйвера Microsoft. Я столкнулся с проблемой, когда, когда я копирую текстовые файлы и файлы Excel в новый каталог и пытаюсь обновить данные, он говорит, что не может найти текстовые файлы. К сожалению, похоже, нет способа сообщить Excel, что я хочу, чтобы пути к текстовым файлам были относительными, а не абсолютными. Все сводные таблицы используют одно и то же подключение к данным, поэтому я решил, что не должно быть слишком сложно написать макрос, который будет обновлять подключение к данным, чтобы ссылаться на правильный текстовый файл, и иметь кнопку, связанную с макросом, который будет обновлять пути к файлам и обновить данные для меня.

Я не слишком хорошо знаком с VBA, и онлайн-документация кажется довольно плохой, поэтому я не смог заставить это работать - я могу создать правильный путь к файлу и могу обновить данные, но я не был смог выяснить, как обновить соединение, чтобы использовать новый путь к файлу, но сохранить все свои старые настройки импорта/анализа файлов. Я также пытался записать макрос при ручном обновлении источника данных, но по какой-то причине это всегда дает мне ошибки, которые прерывают запись, так что это не помогло.

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

Строка подключения:

DefaultDir=C:/directoryPath;Driver={Microsoft Text Driver (*.txt; *.csv)};
  DriverId=27;FIL=text;MaxBufferSize=2048;MaxScanRows=8;PageTimeout=5;
  SafeTransactions=0;Threads=3;UserCommitSync=Yes;

Текст команды:

SELECT *
FROM tableName.txt tableName

Если кто-нибудь знает, как написать макрос, который будет обновлять путь в соединении с текстовым файлом, поделитесь кодом, или если вы знаете, как просто сделать путь относительным, это тоже было бы здорово. Любая помощь будет принята с благодарностью!

ИЗМЕНИТЬ:

Я немного повозился с этим, и мне удалось изменить строки подключения, чтобы использовать новый путь. Однако, когда я обновляю сводную таблицу, она импортирует все данные в виде текста вместо того, чтобы угадывать, должны ли они быть числовыми и т. д. (хотя, по крайней мере, она получает заголовки столбцов из первой строки текстового файла). Любые идеи о том, как сказать ему угадывать типы данных (или просто сохранить старые типы данных)? Код, который я использую прямо сейчас:

Public Sub Test()
    Dim wb As Excel.Workbook
    Dim pc As PivotCache
    Dim path As String

    Set wb = ActiveWorkbook
    path = wb.path

    For Each pc In wb.PivotCaches
        'Debug.Print pc.Connection
        pc.Connection = "ODBC;DBQ=" & path & ";DefaultDir=" & path & ";Driver={Microsoft Text Driver (*.txt; *.csv)};DriverId=27;FIL=text;MaxBufferSize=2048;MaxScanRows=8;PageTimeout=5;SafeTransactions=0;Threads=3;UserCommitSync=Yes"

    Next
End Sub

person scaevity    schedule 24.08.2012    source источник
comment
MsgBox (ThisWorkbook.Path) должно помочь   -  person enderland    schedule 25.08.2012
comment
@enderland Чем это поможет?   -  person scaevity    schedule 25.08.2012
comment
Я думаю, что @enderland пытается сказать, что когда вы используете Thisworkbook.Path, он даст вам полное имя каталога, в котором он находится (однако я думаю, что для серверов он даст вам имя подключенного диска, а не полный UNC дорожка). Вы не можете взять это плюс имя файла, чтобы получить новую переменную DefaultDir. Чтобы получить доступ к этой переменной, я бы предложил записать макрос и снова выполнить подключение к текстовому файлу, чтобы вы увидели, как Excel будет к нему обращаться.   -  person Joseph    schedule 25.08.2012
comment
@ joseph4tw Хорошо, но в моем вопросе выше я сказал, что уже знаю, как получить путь. Я также упомянул, что пытался записать макрос, но постоянно получал ошибки, которые останавливали запись макроса (я могу подключиться к текстовому файлу, но когда я пытаюсь записать процесс, он по какой-то причине больше не работает — может быть, запись мешает соединению или что-то в этом роде, я не знаю).   -  person scaevity    schedule 25.08.2012
comment
@scae вау, я сожалею об этом. Я полностью проглядел эти фразы. Вы можете попробовать зациклиться на QueryTables. Выложу пример.   -  person Joseph    schedule 25.08.2012


Ответы (3)


Итак, у меня все заработало, и я решил поделиться. Я просмотрел каждое соединение в рабочей книге и изменил его путь на новый путь к текстовым файлам (созданным путем получения пути активной рабочей книги и добавления имени каталога текстовых файлов). Кроме того, чтобы убедиться, что он правильно импортировал текстовый файл каждый раз, когда мне нужно было включить файл «schema.ini» с информацией об импорте (в том же каталоге, что и текстовый файл).

person scaevity    schedule 18.09.2012
comment
Я ценю, что вашему сообщению больше 8 лет, и вы, вероятно, перешли ... но если есть шанс, что вы поделитесь своим окончательным кодом (также с использованием файла ini ) - это было бы здорово, поскольку я считаю, что у меня точно есть та же проблема, что и у вас изначально была!? - person Big Chris; 07.02.2021

Я не совсем знаком с созданием сводных таблиц именно таким образом, но обычно вы можете получить информацию о сводной таблице, такой как Connection, просмотрев объект QueryTable. Посмотрите этот пример:

Option Explicit

Public Sub UpdatePivotTableConnections()
    Dim ws As Excel.Worksheet
    Dim qt As Excel.QueryTable
    Dim fileName As String

    For Each ws In ThisWorkbook.Worksheets
        For Each qt In ws.QueryTables
            fileName = GetFileName(qt)
            MsgBox "The file name for PivotTable '" & qt.Name & "' is: " & fileName
        Next
    Next
End Sub

Public Function GetFileName(ByRef qt As QueryTable) As String
    Dim s() As String
    s = Split(qt.Connection, "\")
    GetFileName = s(UBound(s))
End Function

Это не полный ответ, но это начало (мне не нравится публиковать неполные ответы, но это был единственный способ показать вам пример кода). Посмотрите, что вы получите с этой информацией, если вы можете получить доступ к информации оттуда , попробуйте просмотреть строку QueryTable.Connection и посмотреть, как ее можно проанализировать и заменить для каждой сводной таблицы.

person Joseph    schedule 25.08.2012
comment
Итак, я только что попробовал это, и оно работает правильно для обычных таблиц, но не видит сводные таблицы. Любые другие предложения? - person scaevity; 27.08.2012
comment
Он не видит эти сводные таблицы? Это странно. Когда вы щелкаете внутри таблицы, вы получаете меню инструментов сводной таблицы на ленте? Вы можете щелкнуть правой кнопкой мыши в таблице и попасть в меню параметров сводной таблицы? Даже когда я пробую Data->From Text и использую CSV-файл, он все равно создает QueryTable (а не сводную таблицу), к которой я могу получить доступ. Не могли бы вы написать, как вы создаете таблицу, пожалуйста? - person Joseph; 27.08.2012
comment
Я использовал мастер сводных таблиц (alt + d + p) для создания таблиц. На самом деле я понял, как редактировать строки подключения, но теперь у меня возникла новая проблема (см. редактирование в моем вопросе выше). Предложения будут оценены! - person scaevity; 27.08.2012

Я нашел это, и для этого есть много свойств.

    With ActiveSheet.QueryTables.Add(Connection:= _
    "TEXT;\\Path\To\CSV\Folder\CSV_Data.csv" _
    , Destination:=Range("$A$1"))
    .CommandType = 0
    .Name = "Book1"
    .FieldNames = True
    .RowNumbers = False
    .FillAdjacentFormulas = False
    .PreserveFormatting = True
    .RefreshOnFileOpen = False
    .RefreshStyle = xlInsertDeleteCells
    .SavePassword = False
    .SaveData = True
    .AdjustColumnWidth = True
    .RefreshPeriod = 0
    .TextFilePromptOnRefresh = False
    .TextFilePlatform = 437
    .TextFileStartRow = 1
    .TextFileParseType = xlDelimited
    .TextFileTextQualifier = xlTextQualifierDoubleQuote
    .TextFileConsecutiveDelimiter = False
    .TextFileTabDelimiter = True
    .TextFileSemicolonDelimiter = True
    .TextFileCommaDelimiter = False
    .TextFileSpaceDelimiter = False
    .TextFileColumnDataTypes = Array(1, 1, 1)
    .TextFileTrailingMinusNumbers = True
    .Refresh BackgroundQuery:=False
    End With
    End Sub
person Kamal Bharakhda    schedule 27.03.2018