Используя OpenXmlSDK, как я могу выбрать / обновить значение в ячейке, которая является регулятором диапазона? - PullRequest
1 голос
/ 08 декабря 2011

Я даже не уверен, что использую правильную терминологию; Я буду обновлять вопрос и название по мере необходимости.

Я использую OpenXmlSDK для заполнения ранее существующего файла Excel 2010 .xlsm - листа с поддержкой макросов.

Я могу получить доступ к рабочим листам и ячейкам достаточно хорошо.

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

Он помечен как «H13» на листе, и щелкните правой кнопкой мыши >> элемент управления форматом показывает

Input range: 'anotherWorksheet'!$N$3:$N$54
Cell link: 'anotherWorksheet'!$M$3

Всякий раз, когда я пытаюсь получить ссылку на эту ячейку, я не могу ее найти - я получаю null значение

Я пробовал два метода доступа:

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

Я использую OpenXmlSDK для заполнения уже существующего файла Excel 2010 .xlsm - листа с поддержкой макросов.

Я могу получить доступ к рабочим листам и ячейкам достаточно хорошо.

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

Он помечен как «H13» на рабочем листе, и щелкните правой кнопкой мыши >> элемент управления форматом показывает

Input range: 'anotherWorksheet'!$N$3:$N$54
Cell link: 'anotherWorksheet'!$M$3

Всякий раз, когда я пытаюсь получить ссылку на эту ячейку, я не могу ее найти - я получаю null значение

Я пробовал два метода доступа:

    // http://msdn.microsoft.com/en-us/library/ff921204.aspx
    private static Cell GetCell(Worksheet worksheet, string addressName)
    {
        return worksheet.Descendants<Cell>().Where(
          c => c.CellReference == addressName).FirstOrDefault();
    }

и

    // Given a worksheet, a column name, and a row index,
    // gets the cell at the specified column and
    // /615125/open-xml-sdk-2-0-kak-obnovit-yacheiku-v-elektronnoi-tablitse
    private static Cell GetCell(Worksheet worksheet, string columnName, uint rowIndex)
    {
        Row row = GetRow(worksheet, rowIndex);

        if (row == null)
            return null;

        return row.Elements<Cell>().Where(c => string.Compare
               (c.CellReference.Value, columnName +
               rowIndex, true) == 0).FirstOrDefault();
    }

    // Given a worksheet and a row index, return the row.
    private static Row GetRow(Worksheet worksheet, uint rowIndex)
    {
        return worksheet.GetFirstChild<SheetData>().
          Elements<Row>().Where(r => r.RowIndex == rowIndex).First();
    }

Оба дают null для целевой ячейки H13, но предоставляют ссылки на окружающие ячейки (т. Е. `H12, H14, G13 '

На самом деле, I13 также дает null, но эта ячейка не заполнена ничем. Однако, если я не могу получить ссылку, как я могу заполнить ее с помощью SDK? Не моя главная мысль, здесь.

Я буду получать данные, которые будут соответствовать одной из записей в раскрывающемся списке; Мне просто нужно заполнить / выбрать эту конкретную запись в целевой таблице.

Как я могу сделать это с OpenXmlSDK? Я пытался использовать различные библиотеки с открытым исходным кодом, но, похоже, ни одна не поддерживает файлы .xslm (файл, предоставленный клиентом, и его нельзя использовать в другом формате; макросы должны выполняться при запуске и т. Д.).

Хотя я использую C #, так как мой вопрос касается OpenXmlSDK, я бы принял ответы на других языках, используя эту платформу.

1 Ответ

1 голос
/ 09 декабря 2011

Краткий ответ: ячейка не существует, поэтому ссылка null.

Я создал небольшую таблицу со списком (раскрывающимся списком) DataValidation, указывающим на диапазон ячеек в другой таблице.

Отражение файла с помощью инструмента повышения производительности Open XML SDK 2.0 Я увидел, что вместо создания и добавления ячейки на лист создается DataValidation (с CellReference, равным целевому объекту), вместо этого.

    using X14 = DocumentFormat.OpenXml.Office2010.Excel;

    [....]

    X14.DataValidations dataValidations1 = new X14.DataValidations() { Count = (UInt32Value)1U };
    dataValidations1.AddNamespaceDeclaration("xm", "http://schemas.microsoft.com/office/excel/2006/main");

    X14.DataValidation dataValidation1 = new X14.DataValidation() { Type = DataValidationValues.List, AllowBlank = true, ShowInputMessage = true, ShowErrorMessage = true };

    X14.DataValidationForumla1 dataValidationForumla11 = new X14.DataValidationForumla1();
    Excel.Formula formula1 = new Excel.Formula();
    formula1.Text = "Lists!$A$1:$A$51";

    dataValidationForumla11.Append(formula1);
    Excel.ReferenceSequence referenceSequence1 = new Excel.ReferenceSequence();
    referenceSequence1.Text = "A1";

    dataValidation1.Append(dataValidationForumla11);
    dataValidation1.Append(referenceSequence1);

    dataValidations1.Append(dataValidation1);

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

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

НЕ ЯЧЕЙКА: ceci n'est pas un cell

ПРИМЕЧАНИЕ: если выбор сделан из DataValidation и сохранен,ячейка теперь имеет значение, и поэтому оно существует:

IS A CELL: c'est bizarre, non?

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

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

ОБНОВЛЕНИЕ: Я смог найти DataValidation, связанный с ячейкой, найти целевой лист и диапазон, найти целевое значение в этом диапазоне и получить ссылку SharedStringsTable, связанную с этим значением.Но независимо от того, какое значение я подключил к целевой ячейке, Excel открывал все эти данные как плохие.

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

...