SSIS: программно создать новый файл Excel на основе результатов веб-запроса. Как сохранить имена таблиц веб-запросов? - PullRequest
0 голосов
/ 09 января 2019

Что я пытаюсь сделать?

У меня есть список URL-адресов, которые я хочу очистить с помощью функции веб-запросов Excel. Я пытаюсь полностью автоматизировать процесс, поэтому я разрабатываю пакет служб SSIS, который вызывает задачу сценария для каждого URL-адреса. Задача «Сценарий» создает новую книгу Excel с рабочим листом, активирует рабочий лист, добавляет соединение QueryTable, обновляет QueryTable для получения данных, используя XlWebSelectionType.xlAllTables. Затем он сохраняет рабочую книгу и закрывает рабочую книгу и приложение Excel.

Какие технологии я использую?

  • VS 2015 (Предприятие)
  • SQL Server 2016
  • Библиотека объектов Microsoft Excel 16.0
  • Локальная установка Excel из Office 365 ProPlus

В чем проблема?

Хотя задача скрипта сохраняет все данные из таблиц на веб-странице, она помещает их все в одну рабочую таблицу и не сохраняет имена таблиц. Поэтому, хотя мои данные правильно сгруппированы на рабочем листе, у меня нет возможности узнать, какой «группе» данных соответствует какая таблица.

Что мне с этим делать?

В идеале я хотел бы, чтобы каждая таблица QueryTable была сохранена в отдельном рабочем листе с именем таблицы, заданным в качестве имени рабочего листа. За исключением этого, мне нужен способ сохранить имя таблицы с соответствующими данными. Добавление его в качестве нового столбца в QueryTable было бы лучшим в этом сценарии.

Что у меня до сих пор?

Вот основная часть скрипта:

Public Sub Main()
    Dim URL As String = Dts.Variables("User::URL").Value.ToString()
    Dim FileName As String = Dts.Variables("User::FileName").Value.ToString()
    Dim xlNone As XlWebFormatting = XlWebFormatting.xlWebFormattingNone
    Dim Format As XlFileFormat = XlFileFormat.xlCSVWindows
    Dim ScrapeStatus As Integer = 1

    Dim excel As New Microsoft.Office.Interop.Excel.ApplicationClass

    With excel
        .SheetsInNewWorkbook = 1
        .DisplayAlerts = False
    End With

    Dim wb As Microsoft.Office.Interop.Excel.Workbook = excel.Workbooks.Add()

    With wb
        .Activate()
        .Worksheets.Select(1)
    End With

    Try

        Dim rnStart As Range = wb.ActiveSheet.Range("A1:Z100")
        Dim qtQtrResults As QueryTable = wb.ActiveSheet.QueryTables.Add(Connection:="URL;" + URL, Destination:=rnStart)

        With qtQtrResults
            .BackgroundQuery = False
            .WebFormatting = xlNone
            .WebSelectionType = XlWebSelectionType.xlAllTables
            .Refresh()
        End With

        excel.CalculateUntilAsyncQueriesDone()
        wb.SaveAs(FileName)

        wb.Close()
        excel.Quit()
        System.Runtime.InteropServices.Marshal.ReleaseComObject(excel)
        GC.Collect()
        GC.WaitForPendingFinalizers()
        Dts.TaskResult = ScriptResults.Success

    Catch ex As Exception

        Dts.Variables("User::Error").Value = ex.Message.ToString()
        wb.Saved = True
        wb.Close()
        excel.Quit()
        System.Runtime.InteropServices.Marshal.ReleaseComObject(excel)
        GC.Collect()
        GC.WaitForPendingFinalizers()
        Dts.TaskResult = ScriptResults.Failure

    End Try

End Sub

Какие результаты я получаю?

Для URL http://athletics.chabotcollege.edu/information/directory/home#directory, если я использую функциональность веб-запросов в Excel, я могу выбрать из следующего: enter image description here Все имена таблиц отображаются

Однако, когда я извлекаю все таблицы с помощью задачи «Сценарий», я получаю лист, который выглядит примерно так: enter image description here

Другая информация

Следует также отметить, что хотя большинство веб-страниц имеют схожую структуру, не все они одинаковы. Поэтому я не могу предположить, что каждая страница будет иметь одинаковые имена таблиц или структурировать таблицы одинаково. Мое решение должно быть динамичным и гибким.

Ответы [ 2 ]

0 голосов
/ 09 января 2019

Изменяя .WebSelectionType = XlWebSelectionType.xlAllTables на .WebSelectionType = XlWebSelectionType.xlEntirePage, я могу захватить «имена» таблиц. На самом деле это aria-title значения внутри родительского тега <section> каждой таблицы. Это некрасиво, но возвращает строки, которые я ищу.

В итоге я сохранил и QueryTable xlAllTables и xlEntirePage в виде текстовых файлов. Затем я разделяю файл xlAllTables на отдельные фрагменты для каждой таблицы, а затем выполняю поиск в текстовом файле xlEntirePage «строки», представляющей таблицу, и копирую предыдущую строку с заголовком. Затем я сохраняю текст таблицы как новый файл с скопированным заголовком в качестве имени файла. Это очень забавно, но оно сделало то, что мне было нужно.

0 голосов
/ 09 января 2019

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

Кроме того, после проверки документации QueryTable нет возможности получить имена таблиц или заголовок контейнера таблиц, поэтому нет необходимости, чтобы Excel использовал веб-запросы для отображения таблиц и заголовков в Интерфейс (как показано на скриншотах)

Я думаю, что есть один способ разбить данные по таблицам (без имен таблиц):

  1. Вы должны использовать регулярные выражения для получения количества таблиц с веб-страницы <table></table>
  2. Вы должны создать рабочий лист для каждой таблицы
  3. Вы должны создать QueryTable для каждой таблицы
  4. В каждом QueryTable вы должны установить целевой диапазон листа и следующие свойства:

    .WebSelectionType = XlWebSelectionType.xlSpecifiedTables
    .WebTables = i 'Where i is the index of Table
    

Возможно, вам следует использовать анализатор HTML и регулярное выражение для сбора метаданных таблицы

...