25.03.2009, 18:05 | #1 |
Участник
|
Баг при удалении листа Excel
AX 4.0 SP2, класс comExcelDocument_ru, метод deleteSheet() - должен удалять лист Excel по его целочисленному номеру. Обнаружен баг: если лист был переименован (а при этом его номер сохраняется!), то удаление не работает (сообщений никаких не выдается, просто не удаляется).
|
|
25.03.2009, 18:29 | #2 |
Moderator
|
Любопытно. А приведите, пожалуйста, код метода? А то у меня "трёшка", SP4 и такого метода в классе нет.
Вообще, что-то такое попадалось, что по возможности не рекомендуется работать с числовым индексом коллекции Worksheets из-за его нестабильности. Т.е. перебирать коллекцию в цикле по целочисленному индексу можно и гарантируется обход всех листов (в негарантируемом порядке!). А вот насчет прямых обращений - лучше использовать строковый индекc, т.е. имя листа на корешке. А где это видно? В редакторе Visual Basic в дереве листов? Так там отображается значение свойства CodeName, которое рождается вместе с листом и более не меняется - ни при переименовании листа на корешке, ни при перемещении корешка среди других корешков ( его можно поменять только вручную в окне свойств листа в строке "(Name)"). Кстати, как раз индекс в коллекции - это порядковый "номер" корешка, считая слева. И в конструкцию вида Sheets(2).Delete подставляется именно он. |
|
26.03.2009, 09:08 | #3 |
Участник
|
Цитата:
X++: void deleteSheet(int _workSheet) { COM comWorkSheet; ; if (! m_comDocument) throw error(strFmt("@DIS6401", this.getApplicationName())); comWorkSheet = this.getWorkSheet(_workSheet); comWorkSheet.select(); comWorkSheet.delete(); } |
|
26.03.2009, 10:44 | #4 |
Moderator
|
А запустите у себя следующий джоб. Как он отработает? Останется ли лист между листами SheetBeforeDeleted и SheetAfterDeleted?
X++: { ComExcelDocument_RU doc = new ComExcelDocument_RU(); COM sheet; ; doc.newFile(); doc.visible(true); doc.insertSheet(); doc.insertSheet(); doc.insertSheet(); doc.insertSheet(); sheet = doc.getWorkSheet(4); sheet.Select(); sheet.Name('SheetToDelete'); sheet = doc.getWorkSheet(3); sheet.Select(); sheet.Name('SheetBeforeDeleted'); sheet = doc.getWorkSheet(5); sheet.Select(); sheet.Name('SheetAfterDeleted'); sheet = doc.getWorkSheet(4); sheet.Select(); sheet.delete(); } |
|
|
За это сообщение автора поблагодарили: Zabr (1), lev (2). |
26.03.2009, 11:23 | #5 |
Участник
|
Цитата:
Лист1 - Лист5 - SheetBeforeDeleted - SheetAfterDeleted. То есть, 4-й лист удалился. Но непонятно, почему вместо 2-го остался 5-й: ведь мы его переименовали. |
|
26.03.2009, 14:13 | #6 |
Axapta Retail User
|
Цитата:
Т.е. переименовывали лист с номером 5 с названием Лист2 Если метод переписать таким образом: X++: { ComExcelDocument_RU doc = new ComExcelDocument_RU(); COM sheet; ; doc.newFile(); doc.visible(true); doc.insertSheet(0,1); doc.insertSheet(0,2); doc.insertSheet(0,3); doc.insertSheet(0,4); sheet = doc.getWorkSheet(4); sheet.Select(); sheet.Name('SheetToDelete'); sheet = doc.getWorkSheet(3); sheet.Select(); sheet.Name('SheetBeforeDeleted'); sheet = doc.getWorkSheet(5); sheet.Select(); sheet.Name('SheetAfterDeleted'); sheet = doc.getWorkSheet(4); sheet.Select(); sheet.delete(); } Лист1-Лист2-SheetBeforeDeleted-SheetAfterDeleted |
|
26.03.2009, 15:03 | #7 |
Moderator
|
Следим за моим движением.
Я сознательно не использовал второй параметр для insert, чтобы в учебных целях "сбить с толку". Поэтому "Лист2" вставился в конец после "Лист1" и стал активным. Следующий инсерт без второго параметра вставил "Лист3" перед "Лист2" и т.д. Обращаю внимание, что говоря "Лист...", я имею в виду имя этого листа на корешке. После всех вставок, но перед переименованием, корешки листов слева направо выглядят так: Лист1 - Лист5 - Лист4 - Лист3 - Лист2 Соответствующие этим листам индексы коллекции Worksheets идут элементарно в возрастающем порядке (ну просто как счетчик в обычном массиве): 1 - 2 - 3 - 4 - 5 (в интерфейсе это нигде не видно, можно просто считать считать в уме корешки листов слева направо - я выше уже вроде написал про это) т.е. 2-й элемент коллекции Worksheets - это лист с именем "Лист5", а 4-й элемент - "Лист3". После переименования, но до удаления имеем такую ситуацию: Лист1 - Лист5 - SheetBeforeDeleted - SheetToDelete - SheetAfterDeleted ------------------------ 1 - 2 - 3 - 4 - 5 И наконец вид коллекции после удаления листа с индексом 4: Лист1 - Лист5 - SheetBeforeDeleted - SheetAfterDeleted ------------------------ 1 - 2 - 3 - 4 И всё! Не несет в себе автоматически генерируемое имя листа по умолчанию ничего, кроме слова "Лист" (или "Sheet") и следующего номера по порядку. И этот "просто следующий" номер по порядку в общем случае НЕ является текущим индексом листа в коллекции Worksheets! |
|
26.03.2009, 18:39 | #8 |
Участник
|
Спасибо. Классный ответ !
Буду разбираться с нашей версией ComExcelDocument_RU. |
|