Полагаю, я наконец-то прибил этот вопрос - он меня тоже сводил с ума! Было бы неплохо, если бы MS заставила Copy вернуть объект листа, так же, как метод Add ...
Дело в том, что индекс, который VBA выделяет для вновь скопированного листа, фактически не определяется ... как отмечали другие, он очень сильно зависит от скрытых листов. Фактически, я думаю, что выражение Sheets (n) фактически интерпретируется как «n-й видимый лист». Таким образом, если вы не напишите цикл, проверяющий свойство visible каждого листа, использование этого в коде чревато опасностью, если рабочая книга не защищена, поэтому пользователи не могут связываться с свойством visible листов. Слишком тяжело ...
Мое решение этой дилеммы:
- Сделать последний лист видимым (даже временным)
- Скопируйте ПОСЛЕ того листа. ДОЛЖЕН иметь индекс Sheets.Count
- Скрыть прежний последний лист еще раз, если требуется - теперь он будет иметь
индекс Sheets.Count-1
- Переместите новый лист туда, где вы действительно хотите.
Вот мой код, который сейчас кажется пуленепробиваемым ...
Dim sh as worksheet
Dim last_is_visible as boolean
With ActiveWorkbook
last_is_visible = .Sheets(.Sheets.Count).Visible
.Sheets(Sheets.Count).Visible = True
.Sheets("Template").Copy After:=.Sheets(Sheets.Count)
Set sh=.Sheets(Sheets.Count)
if not last_is_visible then .Sheets(Sheets.Count-1).Visible = False
sh.Move After:=.Sheets("OtherSheet")
End With
В моем случае у меня было что-то вроде этого (H указывает на скрытый лист)
1 ... 2 ... 3 (H) ... 4 (H) ... 5 (H) ... 6 ... 7 ... 8 (H) ... 9 (H) )
.Copy After: =. Sheets (2) фактически создает новый лист ДО следующего
Лист VISIBLE - т. Е. Он стал новым индексом 6. НЕ с индексом 3, как вы могли ожидать.
Надеюсь, это поможет ;-)