Хранение многоуровневых данных из книг Excel для сравнения. Не уверен, что коллекция или массив лучше

Стремление найти лучший путь вперед. Мне нужно взять данные из двух отдельных книг Excel, состоящих из нескольких листов, и сохранить некоторые данные с каждого листа в зависимости от типа данных, чтобы я мог позже сравнить эти данные на каждом листе из каждой книги с другой.

Затем я создам еще одну рабочую тетрадь, чтобы обобщить результаты. Это выглядит так:

workbook1->sheetA->uniqueIdentifier->value associated with that identifier
workbook1->sheetB->uniqueIdentifier->value associated with that identifier 

(и так далее для нескольких листов)

Такой же макет и для workbook2. Когда у меня есть данные со всех рабочих листов в каждой книге, я сравниваю данные. Макет листов одинаков в обеих книгах, а «uniqueIdentifier» уникален для этой книги, но также существует и в другой книге. В какой-то момент это вырастет до 3, затем 4, а затем 5 рабочих книг в будущем.

Это похоже на беспорядочный и неэффективный массив, поэтому я подумал, что, возможно, коллекция будет лучше. В любом случае, эту часть проекта кода я только начинаю, поэтому я надеялся получить некоторое представление, прежде чем спуститься в кроличью нору. Сейчас я опираюсь на коллекцию сборников......

Стоит ли изучать 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 называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
0
18
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Не уверен, что это подходит для stackoverflow? Больше похоже на вопрос дизайна. Но вот мои 2 цента.

Мой вариант использования

Я работал над подобным случаем, и в моем случае всегда сравниваются рабочие книги, скажем, wbA и wbB, и в каждой из них есть один лист — sheetA и sheetB.

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

Вход

Для ввода я прошу пользователя дать мне три файла — wbA's excel, «wbB's excel» и configuration json. Перетащите их из ОС и поместите в мою программу, а затем пусть моя программа обрабатывает их. Я также поддерживаю папки, чтобы пользователи могли легко классифицировать свои файлы.

Конфигурация json сообщает мне для любой книги: which sheet to use, which columns to be Primary Key for the rows; и which column in wbA for which column in wbB (я назвал это wiring), если нужно.

Есть также несколько дополнительных настроек, таких как замена строк. Иногда рабочие книги могут содержать строки, которые мне не нужны — я поддерживаю как регулярные выражения, так и буквальные замены для них.

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

Я также слежу за тем, чтобы всякий раз, когда пользователю нужно вводить столбцы (например, установка столбцов PK), я позволял им вводить "A","B","C" вместо номера столбца, такого как 1,2,3. Я сам написал преобразование, для обобщения которого требуется немного математических вычислений, поскольку NPOI берет число, чтобы получить столбец из листа, но IIRC позже обнаружил, что NPOI уже имеет такие встроенные функции. Вы бы хотели сначала проверить, существуют ли они.

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

Если вам трудно это представить, отличная стратегия программирования — начать с простого. Вы начинаете с создания программы, которая может сравнивать две книги, сначала по одному листу в каждой книге, а затем постепенно добавлять в нее дополнительные функции, пока она в конечном итоге не будет соответствовать вашим реальным потребностям.

Сравнение

Я использую NPOI для чтения Excel, а при получении содержимого ячейки я использую XSSFFormulaEvaluator.FormatCellValue() - если я не могу получить книгу ячейки (cell.Row?.Sheet?.Workbook возвращает ноль), поскольку FormulaEvaluator нуждается в ссылке на рабочую книгу происхождения ячейки, я использую просто cell.ToString().

Теперь для сравнения, это похоже на процесс, который вы написали в посте.

  • Создайте первичные ключи для sheetB, сделайте Dictionary<PK, row>. Я просто объединил столбцы PK в строку, например pkA-pkB-pkC....
  • Создайте List<string> из Dictionary.Keys. Список содержит sheetB ключи.
  • Для каждой строки в sheetA сначала создайте первичный ключ, а затем найдите тот же ключ в словаре. Если не найдено, запишите это как ошибку. Если нашли, сравните и сделайте то, что нужно, а также уберите ключ из List<string>. Вам не нужно создавать словари для обоих листов.
  • Наконец, переберите List<string> и запишите их как ошибки — sheetB строка не найдена в sheetA.. и т. д.

Вывод результата

Я вывожу результат сравнения в виде одного файла excel и копирую в него сравниваемые листы. Вывод состоит из трех листов: sheetA, sheetB и result, поэтому пользователи могут быстро просматривать исходные листы при проверке результатов.

... удачи!

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

Xiang Wei Huang 18.05.2022 03:25

отличная информация и детали. спасибо за помощь. это очень ценится!!

bluejuggernaut 18.05.2022 04:33

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