2014-01-04 2 views
0

Я запускаю отчет по электронным таблицам, в котором содержится около 50 столбцов данных в пределах от 1 до 5000 строк. Меня интересуют только 4 столбца, но они никогда не находятся в том же месте, где эти отчеты настроены по-разному для каждого клиента. Затем я беру эти 4 столбца и вставляю в новую книгу, которую я могу импортировать в другую программу.Логика VBA при использовании макросов из personal.xls

У меня создано три макроса, которые выполняют эту задачу безупречно, если они запускались из локального файла. Когда я загружаю их в personal.xls для использования в разных файлах, у меня возникают проблемы. В частности, рабочая книга/рабочий лист ссылаются на проблемы.

Части макроса бегут к листу, который я намереваюсь от них выполнить, в то время как другие части действуют на сам файл personal.xls. Это меня смущает, потому что у меня нет строк, которые используют такие команды, как «thisworkbook» или «activeworksheet».

Например: - Первая строка кодируется для переименования Sheet1. Макрос переименовывает Sheet1 в personal.xls.
- Следующая строка - первая из четырех команд поиска, которые определяют, где находятся интересующие меня столбцы, а затем перемещают их. Этот макрос отлично работает на листе, который я намерен.

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

Может кто-нибудь помочь мне понять, что VBA думает при выполнении макросов из personal.xls и как лучше всего избегать макросов, запущенных на этом листе?

+1

Было бы легче ответить, если бы вы включили некоторые соответствующие биты кода. В общем, вы на правильном пути, потому что вы всегда должны полностью квалифицировать имена книг. –

ответ

2

Есть два подхода, которые вы можете предпринять. Я использую один или оба в своем коде - это не одна или другие ситуации.

объявляются переменные

Начните с определения каждого листа, который вы хотите работать в переменной. Обычно я остаюсь на уровне листа, но это всего лишь личный выбор. Если вы предпочитаете работать на уровне рабочей книги, все в порядке. Процедура может выглядеть так:

Dim shSource as Worksheet 
Dim shDest as Worksheet 

Set shSource = Workbooks("SomeBook").Worksheets(1) 
Set shDest = ActiveWorkbook.Worksheets("Summary") 

тогда, когда я ссылаться на диапазон или клетку или что-нибудь еще на одном листе, я предварить его с этим переменным объектом листа. Даже если мне нужно попасть в книгу, я начинаю с листа. Если мне нужно, например, закрыть исходную книгу из приведенного выше примера, я хотел бы использовать

shSource.Parent.Close False 

настроить шпунтовую переменный мне нужно, и тогда все я делаю, это в терминах этих переменных.

Редактировать

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

Dim wb As Workbook 
Set wb = Workbooks.Open(C:\...) 

Dim ws As Worksheet 
Set ws = Workbooks.Open("C:\...).Worksheets(1) 

или создавая новый, один из этих двух примеров:

Dim wb As Workbook 
Set wb = Workbooks.Add 

Dim ws as Worksheet 
Set ws = Workbooks.Add.Worksheets(1) 

с блоками

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

With Workbook("MyBook") 
    With .Worksheets("First_Sheet") 
     .Range("A1").Value = "stuff" 
    End With 

    With .Worksheets("Second_Sheet") 
     .Range("G10").Formula = "=A1" 
    End With 
End With 

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

Edit 2: Неявное Реферирование

Вы должны всегда явно ссылаться на свои книги и рабочие листы, но она по-прежнему обучающее знать, как Excel будет вести себя, если вы этого не сделаете. Строка кода, начинающаяся как Range("A1").Value = ..., называется неквалифицированной ссылкой. Вы ссылаетесь на диапазон, но вы не говорите, на каком листе его или на какой книге находится этот лист. Excel обрабатывает неквалифицированные ссылки по-разному в зависимости от того, где находится ваш код.

В модуле класса листа (например, когда вы используете события листа, такие как SelectionChange), неквалифицированные ссылки относятся к листу, представленному этим модулем. Если вы находитесь в модуле Sheet1, работающем в событии «Change», и вы вводите код x = Range("G1").Value, тогда G1, на который вы ссылаетесь, находится на Sheet1. В этом случае вы должны использовать ключевое слово Me, а не полагаться на Excel.

В любом другом модуле (например, в стандартном модуле) неквалифицированные ссылки относятся к ActiveSheet. Тот же код x = Range("G1").Value в стандартном модуле относится к G1 на любом листе с фокусом.

Обработка Excel неквалифицированных ссылок очень надежна. Вы можете легко создать надежный код, полагаясь на Excel для разрешения квалифицированных ссылок. Но вы не должны. Ваш код будет более читабельным и более легким для отладки, если вы будете квалифицировать каждую ссылку. Я квалифицирую каждую ссылку. И это не одна из тех вещей, которые я «всегда» делаю, кроме как когда я ленив - я действительно делаю это в 100% случаев.

+0

+1, и есть одна вещь, которую нужно добавить, чтобы дать OP лучше понять, что, вероятно, было ошибкой в ​​его коде: если вы не используете явные ссылки на рабочие листы при доступе к объектам «Range» или «Cell», Excel использует «Активная книга» неявно. –

+0

Эти книги являются временными файлами. Я запускаю их из базы данных, затем сохраняю при необходимости, но файл никогда не будет сохранен с именем файла перед запуском макросов. Разве это не файл, который я только что открыл, рассматривая рабочий справочник? Вы говорите, что personal.xls считается активной рабочей книгой, даже после того, как я открываю новый файл? Если это так, простой ThisWorkBook.Activate в начале каждого из моих макросов должен решить проблему реферирования и заставить макросы запускаться не на personal.xls, а на моих предполагаемых листах, правильно? – SWJ

+0

Да, рабочая книга, которую вы только что открыли, активна. Метод Workbooks.Open возвращает ссылку на рабочую книгу, поэтому лучше назначить переменную в это время. Personal.xls почти никогда не считается активной книгой, потому что она почти всегда скрыта. Если ваш код находится в Personal.xls, и вы пытаетесь его активировать, вы получите сообщение об ошибке bc, вы не сможете активировать скрытую книгу. Не полагайтесь на Excel, чтобы ссылаться на нужную книгу.Всегда ссылайтесь на рабочую книгу и рабочий лист. –

Смежные вопросы