Vba excel как обратиться к другой книге

Обращение к ячейке в другой книге Excel из кода VBA по ссылке, содержащейся в ячейке текущей книги. Переход по ссылке в другую книгу. Примеры.

Ссылки на другую книгу

В ячейку «A1» листа «Лист6» текущей книги вставлена ссылка на ячейку «C12» листа «Лист1» книги «Другая книга.xlsm».

Ссылка в ячейке, если книга «Другая книга.xlsm» открыта:

=‘[Другая книга.xlsm]Лист1’!$C$12

Ссылка в ячейке, если книга «Другая книга.xlsm» закрыта:

=‘C:UsersEvgeniyDesktop[Другая книга.xlsm]Лист1’!$C$12

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

Перед обращением к другой книге необходимо проверить – открыта ли она. Если книга закрыта, ее следует открыть. Один из вариантов кода смотрите в параграфе «Примеры обращения к другой книге».

Обращение к ячейке по ссылке

Обращение из кода VBA Excel к ячейке в другой книге для определения ее координат по ссылке из ячейки «Лист6!A1» текущей книги:

MsgBox Range(ThisWorkbook.Sheets(«Лист6»).Range(«A1»).Formula).Row  ‘Результат = 12

MsgBox Range(ThisWorkbook.Sheets(«Лист6»).Range(«A1»).Formula).Column  ‘Результат = 3

Примеры обращения к другой книге

Условие

В ячейке «A1» листа «Лист6» текущей книги размещена ссылка: ='[Другая книга.xlsm]Лист1'!$C$12. Необходимо перейти по ссылке из ячейки «Лист6!A1» в другую книгу, скопировать диапазон из 9 ячеек (3х3) в другой книге, где первой ячейкой диапазона является ячейка из ссылки, и вставить скопированный диапазон в диапазон «Лист6!A2:C4» текущей книги.

Решение

Если точно известно, что другая книга открыта:

Sub Primer1()

    With ThisWorkbook.Sheets(«Лист6»)

        Range(.Range(«A1»).Formula).Resize(3, 3).Copy .Range(«A2:C4»)

    End With

End Sub

Если неизвестно, открыта другая книга или нет:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

‘Функция для проверки состояния книги (открыта или нет)

Function BookOpenClosed(wbName As String) As Boolean

    Dim myBook As Workbook

    On Error Resume Next

        Set myBook = Workbooks(wbName)

    BookOpenClosed = Not myBook Is Nothing

End Function

Sub Primer2()

Dim s1 As String, s2 As String, s3 As String, n1 As Long, n2 As Long

    ‘записываем ссылку из ячейки Лист6!A1 в переменную s1

    s1 = ThisWorkbook.Sheets(«Лист6»).Range(«A1»).Formula

    ‘вырезаем имя книги из ссылки и записываем в переменную s2

    n1 = InStr(s1, «[«)

    n2 = InStr(s1, «]»)

    s2 = Mid(s1, n1 + 1, n2 n1 1)

        ‘проверяем состояние книги

        If Not BookOpenClosed(s2) Then

            ‘если книга закрыта, вырезаем путь к ней из ссылки и записываем в переменную s3

            n1 = InStr(s1, «:») — 1

            n2 = InStrRev(s1, ««)

            s3 = Mid(s1, n1, n2 n1 + 1)

            ‘открываем другую книгу, объединив путь к ней и ее имя

            Workbooks.Open (s3 & s2)

        End If

    ‘копируем ячейки из другой книги в текущую

    Range(s1).Resize(3, 3).Copy ThisWorkbook.Sheets(«Лист6»).Range(«A2:C4»)

End Sub

И еще один вариант кода VBA Excel для случаев, когда неизвестно, открыта книга или нет. Здесь просто осуществляется попытка открыть книгу, и она будет открыта, если в ячейке содержится ее полное имя, включая диск и подкаталоги. В случае возникновения ошибки, управление будет передано следующей строке.

Sub Primer3()

Dim s1 As String, s2 As String, n1 As Long, n2 As Long

    ‘записываем ссылку из ячейки Лист6!A1 в переменную s1

    s1 = ThisWorkbook.Sheets(«Лист6»).Range(«A1»).Formula

    ‘вырезаем полное имя книги из ссылки и записываем в переменную s2

    On Error Resume Next

    n1 = InStr(s1, «:») — 1

    n2 = InStrRev(s1, «]«)

    s2 = Mid(s1, n1, n2 — n1)

    s2 = Replace(s2, «[«, ««)

    ‘пробуем открыть книгу, если она не открыта

    Workbooks.Open (s2)

    On Error GoTo 0

    ‘копируем ячейки из другой книги в текущую

    Range(s1).Resize(3, 3).Copy ThisWorkbook.Sheets(«Лист6«).Range(«A2:C4«)

End Sub

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


 

VasiliY_Seryugin

Пользователь

Сообщений: 76
Регистрация: 15.10.2018

#1

06.07.2020 18:39:19

Ребят, владею VBA на уровне макрорекордера, поэтому даже элементарных вещей не могу сам осилить.
Поискал через поисковик похожие запросы, но понятного мне ответа не нашел.
Вопрос такой: почему VBA ругается, когда я хочу совершить действие с диапазоном, находящимся в другой книге (в данном случае очистить диапазон), через такое обращение (указание книги, листа и диапазона):

Код
Workbooks("Книга1").worksheets("Лист1").range("A1:B2", Cells.End(xlDown)).ClearContents

Если вначале активировать Книгу1, то ругаться не будет:

Код
workbooks("Книга1").activate
worksheets("Лист1").range("A1:B2", Cells.End(xlDown)).ClearContents

Но ведь как то же можно эту простую команду записать одной строкой, не активируя предварительно книгу, а сразу к ней обращаясь для дальнейших действий?
Как это сделать?

Во вложении пример.
Откройте пример, создайте новую книгу и скопируйте туда кнопки 1 и 2.
При запуске из новой книги Кнопка1 НЕ будет работать (при запуске из родной книги работает).
Кнопка2 работает из любой книги, т.к. в ней стоит предварительная активация нужной книги.
Кнопка3 создана для удобства, чтоб можно было очищенный диапазон восстановить для новых тестов.

Хочу понять, как обратиться к книге «Пример» из другой книги одной строкой, предварительно не используя «Пример».Activate

Прикрепленные файлы

  • Пример.xlsm (22.71 КБ)

 

k61

Пользователь

Сообщений: 2441
Регистрация: 21.12.2012

#2

06.07.2020 18:57:52

Код
Sub Макрон_1_1()
With Workbooks("Пример.xlsm").Worksheets("Лист1")
.Range("A2:I2", .Cells.End(xlDown)).Clear
End With
End Sub

или одной строкой:

Код
Sub Макрон_1_3()
Workbooks("Пример.xlsm").Worksheets("Лист1").Range("A2:I2", Workbooks("Пример.xlsm").Worksheets("Лист1").Cells.End(xlDown)).Clear
End Sub

Изменено: k6106.07.2020 19:01:46

 

VasiliY_Seryugin

Пользователь

Сообщений: 76
Регистрация: 15.10.2018

#3

06.07.2020 19:07:33

K61, спасибо за ответ, но через with мне понятно как делать.
А можно ли это сделать одной строчкой?

Просто в оригинале код у меня выглядит примерно так (фрагмент):

Цитата
Workbooks(«Книга1»).Worksheets(«1»).Range(«A5:C5», Cells.End(xlDown)).Copy
   Workbooks(«Книга2»).Worksheets(«блаблабла»).Range(«A4»).PasteSpecial _
   Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks:=False, Transpose:=False

   Workbooks(«Книга1»).Worksheets(«1»).Range(«E5:K5», Cells.End(xlDown)).Copy
   Workbooks(«Книга2»).Worksheets(«блаблабла»).Range(«D4»).PasteSpecial _
   Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks:=False, Transpose:=False

   Workbooks(«Книга1»).Worksheets(«1»).Range(«D5», Cells.End(xlDown)).Copy
   Workbooks(«Книга2»).Worksheets(«блаблаблаI»).Range(«K4»).PasteSpecial _
   Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks:=False, Transpose:=False

Т.е. многократный перенос данных из Книги1 в Книгу2 значениями.
И каждый раз перед каждой командой активировать книги или делать With не хочется.

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

Изменено: VasiliY_Seryugin06.07.2020 19:08:37

 

VasiliY_Seryugin

Пользователь

Сообщений: 76
Регистрация: 15.10.2018

#4

06.07.2020 19:09:41

Цитата
k61 написал:
или одной строкой:

Ага, это то что нужно!
Я понял чего не так делаю. Спасибо!

 

VasiliY_Seryugin

Пользователь

Сообщений: 76
Регистрация: 15.10.2018

#5

06.07.2020 19:20:51

А еще подскажете, если мне, например, просто нужно выделить этот диапазон, т.е. команда select на конце, вместе Clear, то оно уже почему-то не работает.

Код
Sub Макрон_1_3()
Workbooks("Пример.xlsm").Worksheets("Лист1").Range("A2:I2", Workbooks("Пример.xlsm").Worksheets("Лист1").Cells.End(xlDown)).Select
End Sub

Селектом как к диапазону чужой книги обратиться?

Чтобы, допустим, потом через With selection шрифт поменять, формат ячеек, выравнивание ячеек и т.п.

Изменено: VasiliY_Seryugin06.07.2020 19:24:26

 

k61

Пользователь

Сообщений: 2441
Регистрация: 21.12.2012

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

 

Hugo

Пользователь

Сообщений: 23251
Регистрация: 22.12.2012

А чтоб сделать селект — нужно этот лист активировать! Но для работы с With никакяа активация и селекты не нужны, с чего Вы это взяли?

 

Спасибо. Т.е. обращение селектом к диапазону, находящемуся в другой книге, без Activate не написать получается?

Изменено: VasiliY_Seryugin06.07.2020 20:17:34

 

Hugo

Пользователь

Сообщений: 23251
Регистрация: 22.12.2012

Пишите без селекта, на кой он нужен?

 

VasiliY_Seryugin

Пользователь

Сообщений: 76
Регистрация: 15.10.2018

#10

06.07.2020 20:36:57

Я понял, что я не правильно обращаюсь к диапазону, чтоб его очистить.
Можно ли одной строкой написать код, который будет выделять начальный диапазон «A3:I3», потом выделять все до конца вниз (End(exlDown)), и это дело удалять.

Вот эта красная конструкция у меня не правильная, выявлено опытным путем:
Workbooks(«Пример.xlsm»).Worksheets(«Лист1»).Range(«A3:I3», Cells.End(xlDown)).Copy

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

Вкладываю пример. Если не сложно, помогите сделать чтоб выделялся диапазон с A3:I3 и до конца вниз.

Опять же — одной строкой кода. Макрорекордером можно сделать так:

Код
Range("A3:I3).select
Range(selection, Selection.End(xlDown)).clear

А вот эти все selectы и selection на одну строчку обращения можно заменить?

Прикрепленные файлы

  • Пример.xlsm (22.79 КБ)

 

Юрий М

Модератор

Сообщений: 60575
Регистрация: 14.09.2012

Контакты см. в профиле

VasiliY_Seryugin, лист можно активировать, диапазон можно выделить, но не нужно — это очень замедляет выполнение макроса.

 

Так вот я как раз и не хочу активировать лист и выделать несколько раз диапазон селектом.
У меня есть Книга1, в которой есть макрос.
Нужно чтоб при запуске этого макроса он обращался к Книге2, листу1, выделял на этом листе диапазон «A3:I3», затем через Ctrl+Shift+вниз выделял весь диапазон до конца вниз, и затем очищал выделенное (или копировал, допустим). Вот как это можно максимально коротко записать в коде?

 

Юрий М

Модератор

Сообщений: 60575
Регистрация: 14.09.2012

Контакты см. в профиле

#13

06.07.2020 21:05:40

Вам пишут, что выделять (ВЫДЕЛЯТЬ!) необязательно, а Вы опять за своё:

Цитата
VasiliY_Seryugin написал:
…выделял на этом листе диапазон
 

VasiliY_Seryugin

Пользователь

Сообщений: 76
Регистрация: 15.10.2018

#14

06.07.2020 21:07:04

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

Вот это не работает:

Код
Workbooks("Пример.xlsm").Worksheets("Лист1").Range("A3:I3", Cells.End(xlDown)).Copy

Но вот так работает:

Код
Workbooks("Пример.xlsm").Worksheets("Лист1").Range(Cells(3, 1), Cells(3, 9).End(xlDown)).Copy

Просто синтаксиса не знаю, отсюда и все проблемы.

 

Юрий М

Модератор

Сообщений: 60575
Регистрация: 14.09.2012

Контакты см. в профиле

 

VasiliY_Seryugin

Пользователь

Сообщений: 76
Регистрация: 15.10.2018

#16

06.07.2020 21:28:55

Цитата
VasiliY_Seryugin написал: …я видимо не так объясняю

Нет, все таки при запуске из другой книги не работает все равно без предварительного Activate книги «Пример»  :sceptic:

P.S.
Юрий, вы правы. Иногда стоит еще раз очень внимательно все перечитать снова и снова, и тогда, вероятно, с какого-то раза станет все-таки понятно :)

Вот как мой код должен выглядеть:

Код
Workbooks("Пример.xlsm").Worksheets("Лист1").Range(Workbooks("Пример.xlsm").Worksheets("Лист1").Cells(3, 1), Workbooks("Пример.xlsm").Worksheets("Лист1").Cells(3, 9).End(xlDown)).ClearContents

Всем спасибо!

 

vikttur

Пользователь

Сообщений: 47199
Регистрация: 15.09.2012

#17

06.07.2020 21:45:49

Цитата
VasiliY_Seryugin написал: Вот как… код должен выглядеть
Код
With Workbooks("Пример.xlsm").Worksheets("Лист1")
        .Range(.Cells(3, 1), .Cells(3, 9).End(xlDown)).ClearContents
End With
 

Юрий М

Модератор

Сообщений: 60575
Регистрация: 14.09.2012

Контакты см. в профиле

VasiliY_Seryugin, а именно в одну строку — это самоцель? Ведь длиннее запись получится и не очень читаема. А если с одним диапазоном нужно произвести несколько действий? Конструкция With — Ebd with очень удобная вещь.

 

Hugo

Пользователь

Сообщений: 23251
Регистрация: 22.12.2012

#19

06.07.2020 22:25:24

В первом же ответе и был ответ, и ведь сказали что понятно. Оказываете лукавите? :)

Tim_Coyote

0 / 0 / 0

Регистрация: 10.10.2016

Сообщений: 19

1

Обращение к данным из другой книги

04.07.2017, 16:55. Показов 20001. Ответов 6

Метки нет (Все метки)


Студворк — интернет-сервис помощи студентам

привет!

у меня небольшой и кажется довольно простой вопрос
(сильно упростил задачу, потому что проблема, как мне кажется в этом)

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

Visual Basic
1
2
3
4
5
6
7
8
9
10
Sub TEST()
 
FN = "111.xls"            ' название файла, значение ячейки которого нужно присвоить переменной
SN = "TEST"               ' название листа, значение ячейки которого нужно присвоить переменной
 
With Workbooks(FN).Sheets(SN)
a = Cells(8, 1).Value
End With
 
end sub

но переменной упорно присваивается значение активной книги, а не книги FN

насколько я понял то же самое происходит и с более глобальной задачей

большая просьба помочь)



0



6875 / 2807 / 533

Регистрация: 19.10.2012

Сообщений: 8,562

04.07.2017, 17:09

2

Не умеете использовать with! Посмотрите любой пример — нужна точка перед cells



0



4038 / 1423 / 394

Регистрация: 07.08.2013

Сообщений: 3,541

04.07.2017, 17:11

3

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



0



6875 / 2807 / 533

Регистрация: 19.10.2012

Сообщений: 8,562

05.07.2017, 08:30

4

Цитата
Сообщение от Tim_Coyote
Посмотреть сообщение

находящейся в неактивном листе

— тут ничего не сказано что книга закрыта, значит открыта, значит с точкой должно нормально отработать



0



Tim_Coyote

0 / 0 / 0

Регистрация: 10.10.2016

Сообщений: 19

05.07.2017, 08:40

 [ТС]

5

Hugo121, спасибо, для присвоения значения ячейки работает, а вот для моей задачки — application.sumifs не хочет. все также ищет по активному листу активной книги.

Visual Basic
1
2
3
4
With Workbooks(FN).Sheets(SN)
       a = .Cells(3045, 5).Value          'воткнул проверку, переменной а присваивается правильное значение
         p = .Application.SumIfs(Range("F:F"), Range("A:A"), x, Range("E:E"), b)           ' а вот тут все равно возвращает одни нули..
       End With

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

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



0



6875 / 2807 / 533

Регистрация: 19.10.2012

Сообщений: 8,562

05.07.2017, 11:26

6

Лучший ответ Сообщение было отмечено Tim_Coyote как решение

Решение

Одну точку убрать, три поставить!



1



0 / 0 / 0

Регистрация: 10.10.2016

Сообщений: 19

06.07.2017, 08:23

 [ТС]

7

Hugo121, понял, спасибо) все заработало)



0



Часто бывает, что надо получить данные из другой, открытой вместе с используемой, книги Excel.

Данная функция помогает получить ссылку на другую, открытую в текущий момент, книгу:

Sub ПримерИспользования_GetAnotherWorkbook()
    Dim WB As Workbook
    Set WB = GetAnotherWorkbook
    If Not WB Is Nothing Then
        MsgBox "Выбрана книга: " & WB.FullName, vbInformation
    Else
        MsgBox "Книга не выбрана", vbCritical: Exit Sub
    End If
    ' обработка данных из выбранной книги
    x = WB.Worksheets(1).Range("a2")
    ' ...
End Sub
 
Function GetAnotherWorkbook() As Workbook
    ' если в данный момент открыто 2 книги, функция возвратит вторую открытую книгу
    ' если помимо текущей, открыто более одной книги - будет предоставлен выбор
    On Error Resume Next
    Dim coll As New Collection, WB As Workbook
    For Each WB In Workbooks
        If WB.Name <> ThisWorkbook.Name Then
            If Windows(WB.Name).Visible Then coll.Add CStr(WB.Name)
        End If
    Next WB
    Select Case coll.Count
        Case 0    ' нет других открытых книг
            MsgBox "Нет других открытых книг", vbCritical, "Function GetAnotherWorkbook"
        Case 1    ' открыта ещё только одна книга - её и возвращаем
            Set GetAnotherWorkbook = Workbooks(coll(1))
        Case Else    ' открыто несколько книг - предоставляем выбор
            For i = 1 To coll.Count
                txt = txt & i & vbTab & coll(i) & vbNewLine
            Next i
            msg = "Выберите одну из открытых книг, и введите её порядковый номер:" & _
                  vbNewLine & vbNewLine & txt
            res = InputBox(msg, "Открыто более двух книг", 1)
            If IsNumeric(res) Then Set GetAnotherWorkbook = Workbooks(coll(Val(res)))
    End Select
End Function
  • 37373 просмотра

Не получается применить макрос? Не удаётся изменить код под свои нужды?

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

How do I activate my Other workbook from the Current workbook? I have a current workbook with dumb.xls and The other workbook name as Tire.xls.I have opened the Tire.xls from the dumb.xls using worksbooks.open filename:= "name of the file".Its getting open but The problem is Im unable to make it work.

If I say cells(2,24).value=24 puts these value in the cell of dumb.xls but I want it to be done one Tire.xls.

activesheet.cells(2,24).value=24 puts these on Tire.xls. But how do i activate the Workbook with the name ? I need to open 3 to 4 excel workbooks And perform the operation? How do I activate the specific workbook

I have found this code on google

     activeworkbook.worksheet("sheetname").activate  ' but not working
     windows("sheetname").activate ' people on google suggested not to use

Its not getting activated. I dont know how to make it work. Can anyone tell me How do i activate a specific workbook and a specific sheet of the other workbook ?

Example: I have niko.xls and niko_2.xls opened as workbooks from the dumb.xls workbook so totally 3 workbooks and I have to activate the 2nd sheet of niko_2.xls workbook.How do I make it? Can anyone explain me the syntax with these example? Thank you in advance

Like this post? Please share to your friends:
  • Vba excel как обратиться к диапазону
  • Vba excel как обновить связи
  • Vba excel как обновить лист
  • Vba excel как написать свою функции
  • Vba excel как найти строку с текстом