Резюме
Этот вопрос является продолжением желания создать простой API для электронных таблиц, оставляя его удобным для тех, кто хорошо знает Excel.
Подводя итог, этот вопрос относится к следующим двум:
1. Как реализовать самостоятельное именование столбца из его индекса? ;
2. Как ускорить инициализацию этой пользовательской таблицы? .
Цель
Предоставление упрощенного API-интерфейса Excel, используемого в качестве оболочки для невралгических компонентов, таких как классы / интерфейсы Application
, Workbook
, Worksheet
и Range
, при этом отображаются только наиболее часто используемые свойства объекта для каждого из них.
Пример использования
Этот пример использования основан на модульных тестах, которые позволили мне довести это решение до его нынешнего состояния.
Dim file as String = "C:\Temp\WriteTest.xls"
Using mgr As ISpreadsheetManager = New SpreadsheetManager()
Dim wb as IWorkbook = mgr.CreateWorkbook()
wb.Sheets("Sheet1").Cells("A1").Value = 3.1415926
wb.SaveAs(file)
End Using
А теперь открываем:
Dim file as String = "C:\Temp\WriteTest.xls"
Using mgr As ISpreadsheetManager = New SpreadsheetManager()
Dim wb as IWorkbook = mgr.OpenWorkbook(file)
// Working with workbook here...
End Using
Обсуждение
При создании экземпляра книги Excel:
- Экземпляр рабочего листа автоматически инициализируется в коллекции Workbook.Sheets;
- После инициализации рабочая таблица инициализирует свои ячейки с помощью объекта
Range
, который может представлять одну или несколько ячеек.
Эти ячейки сразу же становятся доступны со всеми их свойствами, как только рабочая таблица существует.
Мое желание - воспроизвести это поведение так, чтобы
- Конструктор класса Workbook инициализирует свойство коллекции Workbook.Sheets с собственными листами;
- Конструктор класса Worksheet инициализирует свойство коллекции Worksheet.Cells собственными ячейками.
Моя проблема возникла из-за конструктора класса Worksheet при инициализации свойства коллекции Worksheet.Cells, показанного в # 2.
Мысли
После этих вышеупомянутых вопросов возникли проблемы, я хочу выяснить другую архитектуру, которая позволила бы мне:
- Доступ к определенной функции ячейки
Range
при необходимости;
- Доставка наиболее часто используемых свойств через мой
ICell
интерфейс;
- Имеет доступ ко всем
Range
ячейкам рабочего листа с момента его инициализации.
Принимая во внимание, что доступ к свойству Range.Value
- это самое быстрое взаимодействие с базовым экземпляром приложения Excel с использованием Interop.
Итак, я подумал об инициализации моего ReadonlyOnlyDictionary(Of String, ICell)
с именем ячеек без немедленного переноса экземпляра интерфейса Range
, чтобы я мог просто сгенерировать индексы строк и столбцов вместе с именем ячейки для индексации моего словаря. затем, присваивая свойство Cell.NativeCell
, только когда требуется получить доступ или отформатировать определенную ячейку или диапазон ячеек.
Таким образом, данные в словаре будут проиндексированы с именем ячеек, полученных из индексов столбцов, сгенерированных в конструкторе класса Worksheet
. Тогда, когда кто-то сделает это:
Using mgr As ISpreadsheetManager = New SpreadsheetManager()
Dim wb As IWorkbook = mgr.CreateWorkbook()
wb.Sheet(1).Cells("A1").Value = 3.1415926 // #1:
End Using
# 1: Это позволило бы мне использовать индексы из моего класса Cell
для записи заданного значения в конкретную ячейку, что быстрее, чем использование его имени непосредственно против Range
.
Вопросы и проблемы
Кроме того, при работе с UsedRange.get_Value()
или Cells.get_Value()
это возвращает массивы Object (,).
1. Так должен ли я быть доволен работой с Object(,)
массивами для ячеек, не имея возможности каким-либо образом его отформатировать?
2. Как спроектировать эти классы Worksheet и Cell, чтобы у меня была лучшая производительность при работе с массивами Object(,)
, при этом сохраняя возможность того, что экземпляр Cell может представлять или оборачивать диапазон Range одной ячейки?
Спасибо всем, кто нашел время, чтобы прочитать мой пост, и мою искреннюю благодарность тем, кто отвечает.