Vba excel изменение значения в ячейке

Всё о работе с ячейками в Excel-VBA: обращение, перебор, удаление, вставка, скрытие, смена имени.

Содержание:

Table of Contents:

  • Что такое ячейка Excel?
  • Способы обращения к ячейкам
    • Выбор и активация
    • Получение и изменение значений ячеек
      • Ячейки открытой книги
      • Ячейки закрытой книги 
    • Перебор ячеек
    • Перебор в произвольном диапазоне
  • Свойства и методы ячеек
    • Имя ячейки
    • Адрес ячейки
    • Размеры ячейки
  • Запуск макроса активацией ячейки

2 нюанса:

  1. Я почти везде стараюсь использовать ThisWorkbook (а не, например, ActiveWorkbook) для обращения к текущей книге, в которой написан этот код (считаю это наиболее безопасным для новичков способом обращения к книгам, чтобы случайно не внести изменения в другие книги). Для экспериментов можете вставлять этот код в модули, коды книги, либо листа, и он будет работать только в пределах этой книги. 
  2. Я использую английский эксель и у меня по стандарту листы называются Sheet1, Sheet2 и т.д. Если вы работаете в русском экселе, то замените Thisworkbook.Sheets(«Sheet1») на Thisworkbook.Sheets(«Лист1»). Если этого не сделать, то вы получите ошибку в связи с тем, что пытаетесь обратиться к несуществующему объекту. Можно также заменить на Thisworkbook.Sheets(1), но это менее безопасно.

Что такое ячейка Excel?

В большинстве мест пишут: «элемент, образованный пересечением столбца и строки». Это определение полезно для людей, которые не знакомы с понятием «таблица». Для того, чтобы понять чем на самом деле является ячейка Excel, необходимо заглянуть в объектную модель Excel. При этом определения объектов «ряд», «столбец» и «ячейка» будут отличаться в зависимости от того, как мы работаем с файлом.

Объекты в Excel-VBA. Пока мы работаем в Excel без углубления в VBA определение ячейки как «пересечения» строк и столбцов нам вполне хватает, но если мы решаем как-то автоматизировать процесс в VBA, то о нём лучше забыть и просто воспринимать лист как «мешок» ячеек, с каждой из которых VBA позволяет работать как минимум тремя способами:

  1. по цифровым координатам (ряд, столбец),
  2. по адресам формата А1, B2 и т.д. (сценарий целесообразности данного способа обращения в VBA мне сложно представить)
  3. по уникальному имени (во втором и третьем вариантах мы будем иметь дело не совсем с ячейкой, а с объектом VBA range, который может состоять из одной или нескольких ячеек). Функции и методы объектов Cells и Range отличаются. Новичкам я бы порекомендовал работать с ячейками VBA только с помощью Cells и по их цифровым координатам и использовать Range только по необходимости.

Все три способа обращения описаны далее

Как это хранится на диске и как с этим работать вне Excel? С точки зрения хранения и обработки вне Excel и VBA. Сделать это можно, например, сменив расширение файла с .xls(x) на .zip и открыв этот архив.

Пример содержимого файла Excel:

Далее xl -> worksheets и мы видим файл листа

Содержимое файла:

 То же, но более наглядно:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<worksheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="x14ac xr xr2 xr3" xmlns:x14ac="http://schemas.microsoft.com/office/spreadsheetml/2009/9/ac" xmlns:xr="http://schemas.microsoft.com/office/spreadsheetml/2014/revision" xmlns:xr2="http://schemas.microsoft.com/office/spreadsheetml/2015/revision2" xmlns:xr3="http://schemas.microsoft.com/office/spreadsheetml/2016/revision3" xr:uid="{00000000-0001-0000-0000-000000000000}">
	<dimension ref="B2:F6"/>
	<sheetViews>
		<sheetView tabSelected="1" workbookViewId="0">
			<selection activeCell="D12" sqref="D12"/>
		</sheetView>
	</sheetViews>
	<sheetFormatPr defaultRowHeight="14.4" x14ac:dyDescent="0.3"/>
	<sheetData>
		<row r="2" spans="2:6" x14ac:dyDescent="0.3">
			<c r="B2" t="s">
				<v>0</v>
			</c>
		</row>
		<row r="3" spans="2:6" x14ac:dyDescent="0.3">
			<c r="C3" t="s">
				<v>1</v>
			</c>
		</row>
		<row r="4" spans="2:6" x14ac:dyDescent="0.3">
			<c r="D4" t="s">
				<v>2</v>
			</c>
		</row>
		<row r="5" spans="2:6" x14ac:dyDescent="0.3">
			<c r="E5" t="s">
				<v>0</v></c>
		</row>
		<row r="6" spans="2:6" x14ac:dyDescent="0.3">
			<c r="F6" t="s"><v>3</v>
		</c></row>
	</sheetData>
	<pageMargins left="0.7" right="0.7" top="0.75" bottom="0.75" header="0.3" footer="0.3"/>
</worksheet>

Как мы видим, в структуре объектной модели нет никаких «пересечений». Строго говоря рабочая книга — это архив структурированных данных в формате XML. При этом в каждую «строку» входит «столбец», и в нём в свою очередь прописан номер значения данного столбца, по которому оно подтягивается из другого XML файла при открытии книги для экономии места за счёт отсутствия повторяющихся значений. Почему это важно. Если мы захотим написать какой-то обработчик таких файлов, который будет напрямую редактировать данные в этих XML, то ориентироваться надо на такую модель и структуру данных. И правильное определение будет примерно таким: ячейка — это объект внутри столбца, который в свою очередь находится внутри строки в файле xml, в котором хранятся данные о содержимом листа.

Способы обращения к ячейкам

Выбор и активация

Почти во всех случаях можно и стоит избегать использования методов Select и Activate. На это есть две причины:

  1. Это лишь имитация действий пользователя, которая замедляет выполнение программы. Работать с объектами книги можно напрямую без использования методов Select и Activate.
  2. Это усложняет код и может приводить к неожиданным последствиям. Каждый раз перед использованием Select необходимо помнить, какие ещё объекты были выбраны до этого и не забывать при необходимости снимать выбор. Либо, например, в случае использования метода Select в самом начале программы может быть выбрано два листа вместо одного потому что пользователь запустил программу, выбрав другой лист.

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

Отменить выбор  ячеек можно методом Unselect:

Selection.Unselect

Отличие выбора от активации — активировать можно только один объект из раннее выбранных. Выбрать можно несколько объектов.

Если вы записали и редактируете код макроса, то лучше всего заменить Select и Activate на конструкцию With … End With. Например, предположим, что мы записали вот такой макрос:

Sub Macro1()
' Macro1 Macro
    Range("F4:F10,H6:H10").Select 'выбрали два несмежных диапазона зажав ctrl
    Range("H6").Activate          'показывает только то, что я начал выбирать второй диапазон с этой ячейки (она осталась белой). Это действие ни на что не влияет
    With Selection.Interior       
        .Pattern = xlSolid
        .PatternColorIndex = xlAutomatic
        .Color = 65535            'залили желтым цветом, нажав на кнопку заливки на верхней панели
        .TintAndShade = 0
        .PatternTintAndShade = 0
    End With
End Sub

Почему макрос записался таким неэффективным образом? Потому что в каждый момент времени (в каждой строке) программа не знает, что вы будете делать дальше. Поэтому в записи выбор ячеек и действия с ними — это два отдельных действия. Этот код лучше всего оптимизировать (особенно если вы хотите скопировать его внутрь какого-нибудь цикла, который должен будет исполняться много раз и перебирать много объектов). Например, так:

Sub Macro11()
'
' Macro1 Macro
    Range("F4:F10,H6:H10").Select '1. смотрим, что за объект выбран (что идёт до .Select)
    Range("H6").Activate
    With Selection.Interior       '2. понимаем, что у выбранного объекта есть свойство interior, с которым далее идёт работа
        .Pattern = xlSolid
        .PatternColorIndex = xlAutomatic
        .Color = 65535
        .TintAndShade = 0
        .PatternTintAndShade = 0
    End With
End Sub



Sub Optimized_Macro()
    With Range("F4:F10,H6:H10").Interior '3. переносим объект напрямую в конструкцию With вместо Selection
' ////// Здесь я для надёжности прописал бы ещё Thisworkbook.Sheet("ИмяЛиста") перед Range,
' ////// чтобы минимизировать риск любых случайных изменений других листов и книг
' ////// With Thisworkbook.Sheet("ИмяЛиста").Range("F4:F10,H6:H10").Interior
        .Pattern = xlSolid               '4. полностью копируем всё, что было записано рекордером внутрь блока with
        .PatternColorIndex = xlAutomatic
        .Color = 55555                   '5. здесь я поменял цвет на зеленый, чтобы было видно, работает ли код при поочерёдном запуске двух макросов
        .TintAndShade = 0
        .PatternTintAndShade = 0
    End With
End Sub

Пример сценария, когда использование Select и Activate оправдано:

Допустим, мы хотим, чтобы во время исполнения программы мы одновременно изменяли несколько листов одним действием и пользователь видел какой-то определённый лист. Это можно сделать примерно так:

Sub Select_Activate_is_OK()
Thisworkbook.Worksheets(Array("Sheet1", "Sheet3")).Select 'Выбираем несколько листов по именам
Thisworkbook.Worksheets("Sheet3").Activate 'Показываем пользователю третий лист
'Далее все действия с выбранными ячейками через Select будут одновременно вносить изменения в оба выбранных листа

'Допустим, что тут мы решили покрасить те же два диапазона:
Range("F4:F10,H6:H10").Select
    Range("H6").Activate
    With Selection.Interior       
        .Pattern = xlSolid
        .PatternColorIndex = xlAutomatic
        .Color = 65535
        .TintAndShade = 0
        .PatternTintAndShade = 0
    End With

End Sub

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

Получение и изменение значений ячеек

Значение ячеек можно получать/изменять с помощью свойства value. 

'Если нужно прочитать / записать значение ячейки, то используется свойство Value
a = ThisWorkbook.Sheets("Sheet1").Cells (1,1).Value 'записать значение ячейки А1 листа "Sheet1" в переменную "a"
ThisWorkbook.Sheets("Sheet1").Cells (1,1).Value = 1  'задать значение ячейки А1 (первый ряд, первый столбец) листа "Sheet1"

'Если нужно прочитать текст как есть (с форматированием), то можно использовать свойство .text:
ThisWorkbook.Sheets("Sheet1").Cells (1,1).Text = "1" 
a = ThisWorkbook.Sheets("Sheet1").Cells (1,1).Text

'Когда проявится разница:
'Например, если мы считываем дату в формате "31 декабря 2021 г.", хранящуюся как дата
a = ThisWorkbook.Sheets("Sheet1").Cells (1,1).Value 'эапишет как "31.12.2021"
a = ThisWorkbook.Sheets("Sheet1").Cells (1,1).Text  'запишет как "31 декабря 2021 г."

Ячейки открытой книги

К ячейкам можно обращаться:

'В книге, в которой хранится макрос (на каком-то из листов, либо в отдельном модуле или форме)
ThisWorkbook.Sheets("Sheet1").Cells(1,1).Value        'По номерам строки и столбца
ThisWorkbook.Sheets("Sheet1").Cells(1,"A").Value      'По номерам строки и букве столбца
ThisWorkbook.Sheets("Sheet1").Range("A1").Value       'По адресу - вариант 1
ThisWorkbook.Sheets("Sheet1").[A1].Value              'По адресу - вариант 2
ThisWorkbook.Sheets("Sheet1").Range("CellName").Value 'По имени ячейки (для этого ей предварительно нужно его присвоить)

'Те же действия, но с использованием полного названия рабочей книги (книга должна быть открыта)
Workbooks("workbook.xlsm").Sheets("Sheet1").Cells(1,1).Value 'По номерам строки и столбца
Workbooks("workbook.xlsm").Sheets("Sheet1").Cells(1,"A").Value                'По номерам строки и букве столбца
Workbooks("workbook.xlsm").Sheets("Sheet1").Range("A1").Value                 'По адресу - вариант 1
Workbooks("workbook.xlsm").Sheets("Sheet1").[A1].Value                        'По адресу - вариант 2
Workbooks("workbook.xlsm").Sheets("Sheet1").Range("CellName").Value           'По имени ячейки (для этого ей предварительно нужно его присвоить)

Ячейки закрытой книги

Если нужно достать или изменить данные в другой закрытой книге, то необходимо прописать открытие и закрытие книги. Непосредственно работать с закрытой книгой не получится, потому что данные в ней хранятся отдельно от структуры и при открытии Excel каждый раз производит расстановку значений по соответствующим «слотам» в структуре. Подробнее о том, как хранятся данные в xlsx см выше.

Workbooks.Open Filename:="С:closed_workbook.xlsx"    'открыть книгу (она становится активной)
a = ActiveWorkbook.Sheets("Sheet1").Cells(1,1).Value  'достать значение ячейки 1,1
ActiveWorkbook.Close False                            'закрыть книгу (False => без сохранения)

Скачать пример, в котором можно посмотреть, как доставать и как записывать значения в закрытую книгу. 

Код из файла:

Option Explicit
Sub get_value_from_closed_wb() 'достать значение из закрытой книги
Dim a, wb_path, wsh As String
wb_path = ThisWorkbook.Sheets("Sheet1").Cells(2, 3).Value 'get path to workbook from sheet1
wsh = ThisWorkbook.Sheets("Sheet1").Cells(3, 3).Value
Workbooks.Open Filename:=wb_path
a = ActiveWorkbook.Sheets(wsh).Cells(3, 3).Value
ActiveWorkbook.Close False
ThisWorkbook.Sheets("Sheet1").Cells(4, 3).Value = a
End Sub

Sub record_value_to_closed_wb() 'записать значение в закрытую книгу
Dim wb_path, b, wsh As String
wsh = ThisWorkbook.Sheets("Sheet1").Cells(3, 3).Value
wb_path = ThisWorkbook.Sheets("Sheet1").Cells(2, 3).Value 'get path to workbook from sheet1
b = ThisWorkbook.Sheets("Sheet1").Cells(5, 3).Value 'get value to record in the target workbook
Workbooks.Open Filename:=wb_path
ActiveWorkbook.Sheets(wsh).Cells(4, 4).Value = b 'add new value to cell D4 of the target workbook
ActiveWorkbook.Close True
End Sub

Перебор ячеек

Перебор в произвольном диапазоне

Скачать файл со всеми примерами

Пройтись по всем ячейкам в нужном диапазоне можно разными способами. Основные:

  1. Цикл For Each. Пример:
    Sub iterate_over_cells()
    
    For Each c In ThisWorkbook.Sheets("Sheet1").Range("B2:D4").Cells
    MsgBox (c)
    Next c
    
    End Sub​

    Этот цикл выведет в виде сообщений значения ячеек в диапазоне B2:D4 по порядку по строкам слева направо и по столбцам — сверху вниз. Данный способ можно использовать для действий, в который вам не важны номера ячеек (закрашивание, изменение форматирования, пересчёт чего-то и т.д.).

  2. Ту же задачу можно решить с помощью двух вложенных циклов — внешний будет перебирать ряды, а вложенный — ячейки в рядах. Этот способ я использую чаще всего, потому что он позволяет получить больше контроля над исполнением: на каждой итерации цикла нам доступны координаты ячеек. Для перебора всех ячеек на листе этим методом потребуется найти последнюю заполненную ячейку. Пример кода:
    Sub iterate_over_cells()
    
    Dim cl, rw As Integer
    Dim x As Variant
    
    'перебор области 3x3
    For rw = 1 To 3 ' цикл для перебора рядов 1-3
    
        For cl = 1 To 3 'цикл для перебора столбцов 1-3
            x = ThisWorkbook.Sheets("Sheet1").Cells(rw + 1, cl + 1).Value
            MsgBox (x)
        Next cl
    Next rw
    
    
    
    'перебор всех ячеек на листе. Последняя ячейка определена с помощью UsedRange
    'LastRow = ActiveSheet.UsedRange.Row + ActiveSheet.UsedRange.Rows.Count - 1
    'LastCol = ActiveSheet.UsedRange.Column + ActiveSheet.UsedRange.Columns.Count - 1
    'For rw = 1 To LastRow 'цикл перебора всех рядов
    '    For cl = 1 To LastCol 'цикл для перебора всех столбцов
    '        Действия 
    '    Next cl
    'Next rw
    
    
    End Sub​
  3. Если нужно перебрать все ячейки в выделенном диапазоне на активном листе, то код будет выглядеть так:
    Sub iterate_cell_by_cell_over_selection()
        Dim ActSheet As Worksheet
        Dim SelRange As Range
        Dim cell As Range
        
     
        Set ActSheet = ActiveSheet
        Set SelRange = Selection
        
        'if we want to do it in every cell of the selected range
        For Each cell In Selection
        MsgBox (cell.Value)
        
        Next cell
    
    End Sub​

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

  4. Перебор ячеек в ряду
    Sub iterate_cells_in_row()
        Dim i, RowNum, StartCell As Long
        
        RowNum = 3 'какой ряд
        StartCell = 0 ' номер начальной ячейки (минус 1, т.к. в цикле мы прибавляем i)
        
        For i = 1 To 10 ' 10 ячеек в выбранном ряду
        ThisWorkbook.Sheets("Sheet1").Cells(RowNum, i + StartCell).Value = i '(i + StartCell) добавляет 1 к номеру столбца при каждом повторении
        Next i
    
    End Sub
  5. Перебор ячеек в столбце
    Sub iterate_cells_in_column()
        Dim i, ColNum, StartCell As Long
        
        ColNum = 3 'какой столбец
        StartCell = 0 ' номер начальной ячейки (минус 1, т.к. в цикле мы прибавляем i)
        
        For i = 1 To 10 ' 10 ячеек
        ThisWorkbook.Sheets("Sheet1").Cells(i + StartCell, ColNum).Value = i ' (i + StartCell) добавляет 1 к номеру ряда при каждом повторении
        Next i
    
    End Sub​

Свойства и методы ячеек

Имя ячейки

Присвоить новое имя можно так:

Thisworkbook.Sheets(1).Cells(1,1).name = "Новое_Имя"

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

ActiveWorkbook.Names("Старое_Имя").Delete

Пример кода для переименования ячеек:

Sub rename_cell()

old_name = "Cell_Old_Name"
new_name = "Cell_New_Name"

ActiveWorkbook.Names(old_name).Delete
ThisWorkbook.Sheets(1).Cells(2, 1).Name = new_name
End Sub

Sub rename_cell_reverse()

old_name = "Cell_New_Name"
new_name = "Cell_Old_Name"

ActiveWorkbook.Names(old_name).Delete
ThisWorkbook.Sheets(1).Cells(2, 1).Name = new_name
End Sub

Адрес ячейки

Sub get_cell_address() ' вывести адрес ячейки в формате буква столбца, номер ряда
  '$A$1 style
  txt_address = ThisWorkbook.Sheets(1).Cells(3, 2).Address
  MsgBox (txt_address)
End Sub

Sub get_cell_address_R1C1()' получить адрес столбца в формате номер ряда, номер столбца
  'R1C1 style
  txt_address = ThisWorkbook.Sheets(1).Cells(3, 2).Address(ReferenceStyle:=xlR1C1)
  MsgBox (txt_address)
End Sub

  'пример функции, которая принимает 2 аргумента: название именованного диапазона и тип желаемого адреса 
  '(1- тип $A$1 2- R1C1 - номер ряда, столбца)
Function get_cell_address_by_name(str As String, address_type As Integer)
  '$A$1 style
  Select Case address_type
    Case 1
      txt_address = Range(str).Address
    Case 2
      txt_address = Range(str).Address(ReferenceStyle:=xlR1C1)
    Case Else
      txt_address = "Wrong address type selected. 1,2 available"
    End Select
  get_cell_address_by_name = txt_address
End Function

'перед запуском нужно убедиться, что в книге есть диапазон с названием, 
'адрес которого мы хотим получить, иначе будет ошибка
Sub test_function() 'запустите эту программу, чтобы увидеть, как работает функция
  x = get_cell_address_by_name("MyValue", 2)
  MsgBox (x)
End Sub

Размеры ячейки

Ширина и длина ячейки в VBA меняется, например, так:

Sub change_size()
Dim x, y As Integer
Dim w, h As Double

'получить координаты целевой ячейки
x = ThisWorkbook.Sheets("Sheet1").Cells(2, 2).Value
y = ThisWorkbook.Sheets("Sheet1").Cells(3, 2).Value

'получить желаемую ширину и высоту ячейки
w = ThisWorkbook.Sheets("Sheet1").Cells(6, 2).Value
h = ThisWorkbook.Sheets("Sheet1").Cells(7, 2).Value

'сменить высоту и ширину ячейки с координатами x,y
ThisWorkbook.Sheets("Sheet1").Cells(x, y).RowHeight = h
ThisWorkbook.Sheets("Sheet1").Cells(x, y).ColumnWidth = w


End Sub

Прочитать значения ширины и высоты ячеек можно двумя способами (однако результаты будут в разных единицах измерения). Если написать просто Cells(x,y).Width или Cells(x,y).Height, то будет получен результат в pt (привязка к размеру шрифта). 

Sub get_size()
Dim x, y As Integer
'получить координаты ячейки, с которой мы будем работать
x = ThisWorkbook.Sheets("Sheet1").Cells(2, 2).Value
y = ThisWorkbook.Sheets("Sheet1").Cells(3, 2).Value

'получить длину и ширину выбранной ячейки в тех же единицах измерения, в которых мы их задавали
ThisWorkbook.Sheets("Sheet1").Cells(2, 6).Value = ThisWorkbook.Sheets("Sheet1").Cells(x, y).ColumnWidth
ThisWorkbook.Sheets("Sheet1").Cells(3, 6).Value = ThisWorkbook.Sheets("Sheet1").Cells(x, y).RowHeight

'получить длину и ширину с помощью свойств ячейки (только для чтения) в поинтах (pt)
ThisWorkbook.Sheets("Sheet1").Cells(7, 9).Value = ThisWorkbook.Sheets("Sheet1").Cells(x, y).Width
ThisWorkbook.Sheets("Sheet1").Cells(8, 9).Value = ThisWorkbook.Sheets("Sheet1").Cells(x, y).Height

End Sub

Скачать файл с примерами изменения и чтения размера ячеек

Запуск макроса активацией ячейки

Для запуска кода VBA при активации ячейки необходимо вставить в код листа нечто подобное:

3 важных момента, чтобы это работало:

1. Этот код должен быть вставлен в код листа (здесь контролируется диапазон D4)

2-3. Программа, ответственная за запуск кода при выборе ячейки, должна называться Worksheet_SelectionChange и должна принимать значение переменной Target, относящейся к триггеру SelectionChange. Другие доступные триггеры можно посмотреть в правом верхнем углу (2).

Скачать файл с базовым примером (как на картинке)

Скачать файл с расширенным примером (код ниже)

Option Explicit

Private Sub Worksheet_SelectionChange(ByVal Target As Range)

        ' имеем в виду, что триггер SelectionChange будет запускать эту Sub после каждого клика мышью (после каждого клика будет проверяться:
          '1. количество выделенных ячеек и 
          '2. не пересекается ли выбранный диапазон с заданным в этой программе диапазоном.
        ' поэтому в эту программу не стоит без необходимости писать никаких других тяжелых операций

    If Selection.Count = 1 Then 'запускаем программу только если выбрано не более 1 ячейки


    'вариант модификации - брать адрес ячейки из другой ячейки:
    'Dim CellName as String
    'CellName = Activesheet.Cells(1,1).value 'брать текстовое имя контролируемой ячейки из A1 (должно быть в формате Буква столбца + номер строки)
    'If Not Intersect(Range(CellName), Target) Is Nothing Then
    'для работы этой модификации следующую строку надо закомментировать/удалить



        If Not Intersect(Range("D4"), Target) Is Nothing Then 
        'если заданный (D4) и выбранный диапазон пересекаются 
        '(пересечение диапазонов НЕ равно Nothing)

        'можно прописать диапазон из нескольких ячеек:
        'If Not Intersect(Range("D4:E10"), Target) Is Nothing Then
        'можно прописать несколько диапазонов:
        'If Not Intersect(Range("D4:E10"), Target) Is Nothing or Not Intersect(Range("A4:A10"), Target) Is Nothing Then

            Call program 'выполняем программу
        End If
    End If
End Sub

Sub program()

MsgBox ("Program Is running") 'здесь пишем код того, что произойдёт при выборе нужной ячейки


End Sub

Запуск макроса (процедуры) из кода VBA Excel при изменении значения ячейки вручную или программным способом, а также при нажатии клавиши Delete.

Запуск макроса при изменении ячейки

Пример кода

Код VBA Excel для запуска макроса (процедуры) при изменении значения ячейки на рабочем листе:

Private Sub Worksheet_Change(ByVal Target As Range)

    If Not Application.Intersect(Range(«A1:D8»), Range(Target.Address)) Is Nothing Then

        MsgBox «Значение ячейки « & Target.Address & » изменено.»

    End If

End Sub

Range("A1:D8") — это диапазон, при изменении значения любой ячейки которого, произойдет выполнение функции MsgBox. Диапазон может состоять из одной ячейки.

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

Вместо функции MsgBox в приведенном коде следует разместить ссылку на исполняемую процедуру (макрос) VBA Excel.

Примечания

  • Макрос будет запущен при изменении значения ячейки вручную или программным способом, а также при нажатии клавиши Delete.
  • Вызываемая процедура будет запущена и в том случае, если в ячейку будет записано то же самое значение, которое в ней и было. Например, в ячейке было число 28, и в нее записали вручную или программно число 28; или нажали клавишу Delete на пустой ячейке.
  • Макрос не будет запущен при изменении значения ячейки с формулой в результате ее пересчета.

Исключение ложного срабатывания

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

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

Option Explicit

Dim x

Private Sub Worksheet_Activate()

x = Range(«C4»)

End Sub

Private Sub Worksheet_Change(ByVal Target As Range)

    If Not Application.Intersect(Range(«A1:D8»), Range(Target.Address)) Is Nothing _

    And x <> Range(«C4») Then

        MyMsgBox

        x = Range(«C4»)

    End If

End Sub

Private Sub MyMsgBox()

    MsgBox «Значение ячейки « & «C4» & » изменено на « & Chr(34) & Range(«C4») & Chr(34)

End Sub

В это примере функция MsgBox вынесена в отдельную процедуру, которая вызывается при изменении значения в ячейке C4.

Значение ячейки C4 присваивается переменной x при активации рабочего листа и, затем, перезаписывается при каждой перезаписи значения в ячейке.

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


We use VBA to automate our tasks in excel. The idea of using VBA is to connect the interface of excel with the programming. One of the very most connections between them is by changing the cell values. The change in cell value by programming shows the power of VBA. In this article, we will see how to set, get and change the cell value. 

Set Cell Value

Assigning a cell with a value can be achieved by very two famous functions in VBA i.e. Range and Cells function. 

Range Function in VBA

The range function helps access the cells in the worksheet. To set the cell value using the range function, we use the .Value

Syntax: Range(cell_name).Value = value_to_be_assinged. 

Set the value to a single cell

If you want to assign ’11’ to cell A1, then the following are the steps: 

Step 1: Use the Range function, in the double quotes type the cell name. Use .Value object function. For example, Range(“A1”).Value = 11

Applying-range-function

Step 2: Run your macro. The number 11 appears in cell A1

Running-macro

Set the value to multiple cells at the same time

Remember the days, when your teacher gives you punishment, by making you write the homework 10 times, those were the hard days, but now the effort has exponentially reduced. You can set a value to a range of cells with just one line of code. If you want to write your name, for example, “Arushi” 10 times, in the range A2 to A11. Use range function. Following are the steps: 

Step 1: Use the Range function, in the double quotes, write “Start_of_cell: End_of_cell”. Use .Value object function. For example, Range(“A2:A11”).Value = “Arushi”

Applying-range-function

Step 2: Run your macro. The text “Arushi” appears from cell A2 to A11 inclusive. 

Running-macro

Cells Function in VBA

The Cells function is similar to the range function and is also used to set the cell value in a worksheet by VBA. The difference lies in the fact that the Cells function can only set a single cell value at a time while the Range function can set multiple values at a time. Cells function use matrix coordinate system to access cell elements. For example, A1 can be written as (1, 1), B1 can be written as (1, 2), etc. 

Syntax: Cells(row_number, column_number).Value = value_to_be_assign

For example, you want to set the cell value to “Arushi cleared CA with Rank “, in cell B1. Also, set cell C1, to ‘1’. Following are the steps:

Step 1: Open your VBA editor. Use cells function, as we want to access cell B1, the matrix coordinates will be (1, 2). Type, Cells(1, 2).Value = “Arushi cleared CA with Rank” in the VBA code. 

Using-cell-functions

Step 2: To access cell C1, the matrix coordinates are (1, 3). Type, Cells(1, 3).Value = 1 in the VBA code. 

Accessing-cell-C1

Step 3: Run your macro. The required text appears in cell B1, and a number appears in C1. 

Running-macro

Setting Cell values by Active cell and the input box

There are other ways by which you can input your value in the cell in a worksheet. 

Active Cell 

You can set the cell value of a cell that is currently active. An active cell is the selected cell in which data is entered if you start typing. Use ActiveCell.Value object function to set the value either to text or to a number. 

Syntax: ActiveCell.Value = value_to_be_assigned

For example, you want to assign the active cell with a text i.e. “Arushi is practicing CA”, also want to change the color of the cell to yellow. Following are the steps: 

Step 1: Use the ActiveCell object to access the currently selected cell in the worksheet. Use ActiveCell.Value function object to write the required text. 

Using-active-cell-function

Step 2: Color the cell by using ActiveCell.Interior.Color function. For example, use vbYellow to set your cell color to yellow. 

Using-active.cell.interior.color-function

Step 3: Run your macro. The currently selected cell i.e. B1 has attained the requirements. 

Running-macro

Input Box

You can use the input box to set the cell value in a worksheet. The input box takes the custom value and stores the result. This result could further be used to set the value of the cell. For example, set the cell value of A1, dynamically by taking input, from the input box.

Following are the steps

Step 1: Open your VBA editor. A sub-procedure name geeks() is created. Use the Range function to store the value given by the input box. 

Using-range-function

Step 2: Run your Macro. A dialogue-box name Microsoft Excel appears. Enter the value to be stored. For example, “geeks for geeks”. Click Ok

Entering-value-to-be-stored

Step 3: Open your worksheet. In cell A1, you will find the required text is written. 

Text-written-in-A1

Get Cell Value

After setting the cell value, it’s very important to have a handsome knowledge of how to display the cell value. There can be two ways two get the cell value either print the value in the console or create a message box. 

Print Cell Value in Console

The console of the VBA editor is the immediate window. The immediate window prints the desired result in the VBA editor itself. The cell value can be stored in a variable and then printed in the immediate window. For example, you are given a cell A1 with the value ’11’, and you need to print this value in the immediate window. 

Following are the steps

Step 1: Press Ctrl + G to open the immediate window. 

Opening-immediate-window

Step 2: The cell value in A1 is 1

Value-in-A1

Step 3: Open your VBA editor. Declare a variable that could store the cell value. For example, Val is the variable that stores the cell value in A1. Use the Range function to access the cell value. After storing the cell value in the val, print the variable in the immediate window with the help of Debug.Print(val) function.

Printing-variable-in-immediate-window

Step 4: Run your macro. The cell value in A1 is printed in the immediate window. 

Running-macro

Print Cell Value in a Message Box 

A message box can also be used to show the cell value in VBA. For example, a random string is given in cell A1 of your string i.e. “Arushi studies in Hansraj”. Now, if you want to display the cell value in A1, we can use Message Box to achieve this. 

Text-present-in-A1

Following are the steps

Step 1: Open your VBA macro. Create a message box by using MsgBox. Use the Range(cell).Value function to access the cell value. 

Creating-a-message-box

Step 2: Run your macro. A message box appears, which contains the cell value of A1

Running-macro

Change Cell Values 

The value, once assigned to the cell value, can be changed. Cell values are like variables whose values can be changed any number of times. Either you can simply reassign the cell value or you can use different comparators to change the cell value according to a condition. 

By reassigning the Cell Value

You can change the cell value by reassigning it. In the below example, the value of cell A1 is initially set to 1, but later it is reassigned to 2

Following are the steps

Step 1: Open your VBA code editor. Initially, the value of cell A1 is assigned to 1. This initial value is printed in the immediate window. After that, we changed the value of cell A1 to 2. Now, if we print the A1 value in the immediate window, it comes out to be 2

Changing-value-in-cell

Step 2: The immediate window shows the output as 1 and 2. 

Immediate-window-shows-output

Changing cell value with some condition

We can use if-else or switch-case statements to change the cell value with some condition. For example, if your age is greater than 18 then you can drive else you cannot drive. You can output your message according to this condition. 

Following are the steps

Step 1: A code is written in the image below, which tells whether you are eligible for a driving license or not. If your age is greater than 18 then cell A1 will be assigned with the value, “You are eligible for the driving license”, else A1 will be assigned with “You are not eligible for driving license”. 

Text-assigned-to-A1

Step 2: Run your macro. An input box appears. Enter your age. For example, 19. 

Running-macro

Step 3: According to the age added the cell value will be assigned. 

Cell-value-assigned

Обычно в Excel мы можем нажать клавишу F5 или кнопку «Выполнить», чтобы выполнить код VBA. Но пробовали ли вы когда-нибудь запустить конкретный код макроса при изменении значения ячейки? В этой статье я расскажу о некоторых быстрых приемах, которые помогут справиться с этой задачей в Excel.

Запуск или вызов макроса при изменении значения определенной ячейки с кодом VBA

Запуск или вызов макроса при изменении любого значения ячейки в диапазоне с кодом VBA


стрелка синий правый пузырь Запуск или вызов макроса при изменении значения определенной ячейки с кодом VBA

Чтобы запустить код макроса, изменив значение ячейки, следующий код VBA может оказать вам услугу, сделайте следующее:

1. Щелкните правой кнопкой мыши вкладку листа, на которой вы хотите выполнить макрос, если значение ячейки изменится, а затем выберите Просмотреть код из контекстного меню, а в открывшемся Microsoft Visual Basic для приложений окна, скопируйте и вставьте следующий код в пустой модуль:

Код VBA: запускать макрос при изменении значения ячейки:

Private Sub Worksheet_Change(ByVal Target As Range)
    If Target.Address = "$A$1" Then
        Call Mymacro
    End If
End Sub

doc запускает макрос, если ячейка изменяется 1

Внимание: В приведенном выше коде A1 это конкретная ячейка, на основе которой вы хотите запустить код, Mymacro это имя макроса, который вы хотите запустить. Пожалуйста, измените их по своему усмотрению.

2. А затем сохраните и закройте окно кода, теперь, когда вы вводите или изменяете значение в ячейке A1, определенный код будет запускаться сразу.


стрелка синий правый пузырь Запуск или вызов макроса при изменении любого значения ячейки в диапазоне с кодом VBA

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

1. Щелкните правой кнопкой мыши вкладку листа, на которой вы хотите выполнить макрос, если значение ячейки изменится, а затем выберите Просмотреть код из контекстного меню, а в открывшемся Microsoft Visual Basic для приложений окна, скопируйте и вставьте следующий код в пустой модуль:

Код VBA: запускать макрос при изменении любого значения ячейки в диапазоне:

Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Target, Range("A1:B100")) Is Nothing Then
Call Mymacro
End If
End Sub

doc запускает макрос, если ячейка изменяется 2

Внимание: В приведенном выше коде A1: B100 это конкретные ячейки, на основе которых вы хотите запустить код, Mymacro это имя макроса, который вы хотите запустить. Пожалуйста, измените их по своему усмотрению.

2. А затем сохраните и закройте окно кода, теперь, когда вы вводите или изменяете значение в любой ячейке A1: B100, конкретный код будет выполнен сразу.



Статьи по теме:

Как запустить макрос автоматически перед печатью в Excel?

Как запустить макрос на основе значения ячейки в Excel?

Как запустить макрос на основе значения, выбранного из раскрывающегося списка в Excel?

Как запустить макрос, щелкнув гиперссылки в Excel?

Как запустить макрос, когда лист выбран из книги?


Лучшие инструменты для работы в офисе

Kutools for Excel Решит большинство ваших проблем и повысит вашу производительность на 80%

  • Снова использовать: Быстро вставить сложные формулы, диаграммы и все, что вы использовали раньше; Зашифровать ячейки с паролем; Создать список рассылки и отправлять электронные письма …
  • Бар Супер Формулы (легко редактировать несколько строк текста и формул); Макет для чтения (легко читать и редактировать большое количество ячеек); Вставить в отфильтрованный диапазон
  • Объединить ячейки / строки / столбцы без потери данных; Разделить содержимое ячеек; Объединить повторяющиеся строки / столбцы… Предотвращение дублирования ячеек; Сравнить диапазоны
  • Выберите Дубликат или Уникальный Ряды; Выбрать пустые строки (все ячейки пустые); Супер находка и нечеткая находка во многих рабочих тетрадях; Случайный выбор …
  • Точная копия Несколько ячеек без изменения ссылки на формулу; Автоматическое создание ссылок на несколько листов; Вставить пули, Флажки и многое другое …
  • Извлечь текст, Добавить текст, Удалить по позиции, Удалить пробел; Создание и печать промежуточных итогов по страницам; Преобразование содержимого ячеек в комментарии
  • Суперфильтр (сохранять и применять схемы фильтров к другим листам); Расширенная сортировка по месяцам / неделям / дням, периодичности и др .; Специальный фильтр жирным, курсивом …
  • Комбинируйте книги и рабочие листы; Объединить таблицы на основе ключевых столбцов; Разделить данные на несколько листов; Пакетное преобразование xls, xlsx и PDF
  • Более 300 мощных функций. Поддерживает Office/Excel 2007-2021 и 365. Поддерживает все языки. Простое развертывание на вашем предприятии или в организации. Полнофункциональная 30-дневная бесплатная пробная версия. 60-дневная гарантия возврата денег.

вкладка kte 201905


Вкладка Office: интерфейс с вкладками в Office и упрощение работы

  • Включение редактирования и чтения с вкладками в Word, Excel, PowerPoint, Издатель, доступ, Visio и проект.
  • Открывайте и создавайте несколько документов на новых вкладках одного окна, а не в новых окнах.
  • Повышает вашу продуктивность на 50% и сокращает количество щелчков мышью на сотни каждый день!

офисный дно

 

OSA913

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

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

#1

25.07.2017 08:31:02

Доброе утро! Помогите заставить правильно работать макрос.

Скрытый текст

Он рабочий, но только любые изменения в любых ячейках на этом листе другими макросами, они(другие макросы) всегда обращаются к этой процедуре, что замедляет работу макроса. Нужно чтобы к этой процедуре было обращение только когда происходит изменение в ячейке указанной в этой процедуре но ни как не в каждой ячейке. Я пытался подставить код как рекомендует Юрий М

тут

но не известно почему не вышло.

Изменено: OSA91325.07.2017 08:34:47

 

webley

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

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

#2

25.07.2017 09:21:16

что-то в этом роде:

Код
Private Sub Worksheet_Change(ByVal Target As Range)
    If Target.Address = Range("A1").Address Then
        '<код>
    ElseIf Target.Address = Range("B1").Address Then
        '<код>
    End If
End Sub
 

Sanja

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

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

#3

25.07.2017 09:47:49

Код
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Target, Range("D3,F3,X3,Z3,AR3,AT3,AR5,AT5")) Is Nothing And Target.Count = 1 Then
    On Error Resume Next
    Application.ScreenUpdating = False
    Application.EnableEvents = False
    Select Case Target.Address
        Case "$D$3"
            Set KeyCells = Range("M3")
        Case "$F$3"
            Set KeyCells = Range("N3")
        Case "$X$3"
            Set KeyCells = Range("AE3")
        Case "$Z$3"
            Set KeyCells = Range("AG3")
        Case "$AR$3"
            Set KeyCells = Range("AX3")
        Case "$AT$3"
            Set KeyCells = Range("AY3")
        Case "$AR$5"
            Set KeyCells = Range("BA3")
        Case "$AT$5"
            Set KeyCells = Range("BC3")
    End Select
    KeyCells = Target
    CopyData1
End If
Application.EnableEvents = True
Application.ScreenUpdating = True
End Sub

Изменено: Sanja25.07.2017 15:55:58

Согласие есть продукт при полном непротивлении сторон.

 

OSA913

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

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

Спасибо, но пока не работает макрос(

 

Sanja

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

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

Покажите файл-пример

Согласие есть продукт при полном непротивлении сторон.

 

OSA913

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

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

Когда в vba клавишей F8 проверяю ход выполнения макроса «QQ», он заходит в процедуру «Private Sub Worksheet_Change» после  изменения значения в каждой ячейке. Нужно чтобы в «Private Sub Worksheet_Change»  желтая стрелка не попадала.

Изменено: OSA91325.07.2017 11:43:38

 

OSA913

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

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

Вариант webley так же работает как мой. Может так должно быть ..?

 

Sanja

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

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

#8

25.07.2017 15:36:20

Цитата
OSA913 написал: заходит в процедуру «Private Sub Worksheet_Change» после  изменения значения в каждой ячейке

Правильно. Потому что возникает событие Изменения ячейки

Согласие есть продукт при полном непротивлении сторон.

 

Sanja

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

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

#9

25.07.2017 15:51:42

Цитата
OSA913 написал: но пока не работает макрос

Что значит не работает? Вы поймите, что Событие изменения ячейки возникает при изменении ЛЮБОЙ ячейки на листе, и обработчик этого события (Private Sub Worksheet_Change) будет выполняться в ЛЮБОМ случае. Другое дело КАК он будет выполняться. Проверьте мой макрос (чуть подкорректировал его в сообщении #3) и сравните время выполнения со своим. У Вас же проблема в том что работа макроса замедляется. Но это именно из-за того, что Ваш код написан не оптимально

Согласие есть продукт при полном непротивлении сторон.

 

OSA913

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

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

Доброе утро! Sanja, сам макрос не работает именно Ваш вариант. Посмотрите пожалуйста в примере. Сверху  два варианта за комментированные они работают.

 

Александр

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

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

#11

26.07.2017 06:35:03

OSA913, У вас

Код
Case "A1"

У Sanja

Код
Case "$D$3"

Разницу улавливаете ?)
Target.Address возвращает «$A$1» а не «A1»

 

OSA913

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

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

 

OSA913,А я собственно не понимаю, как оно должно работать ?)  Так нужно ?

 

OSA913

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

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

Точно. Спасибо! Действительно оптимальней такой вариант. Только теперь макрос «CopyData1» не всегда срабатывает. Как его поставить в коде чтобы он срабатывал всегда при изменении значения в любой ячейке листа?

 

Sanja

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

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

#15

26.07.2017 13:53:27

Цитата
OSA913 написал:
теперь макрос «CopyData1» не всегда срабатывает

Перенесите CopyData1 после End If

Согласие есть продукт при полном непротивлении сторон.

 

OSA913

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

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

#16

26.07.2017 18:35:36

Цитата
Sanja написал:
Перенесите CopyData1 после End If

Будет непрерывный цикл т.к. CopyData1 меняя значения в ячейках снова возвращается в «Private Sub Worksheet_Change».

 

Sanja

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

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

#17

26.07.2017 18:43:26

Логично. Тогда отключайте обработку событий сразу после начала процедуры

Код
Private Sub Worksheet_Change(ByVal Target As Range)
Application.ScreenUpdating = False
Application.EnableEvents = False
If Not Intersect(Target, Range("A1,A2,A3,A4,A5,A6,A7,A8")) Is Nothing And Target.Count = 1 Then
    On Error Resume Next
    Select Case Target.Address
    .......

Согласие есть продукт при полном непротивлении сторон.

 

Sanja

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

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

#18

26.07.2017 18:46:19

Цитата
Sanja написал: Логично…

Хотя не совсем. Мы же не знаем что Ваш макрос CopyData1 делает. Может он не изменяет ячейки на текущем листе

Согласие есть продукт при полном непротивлении сторон.

 

OSA913

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

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

Работает! Спасибо друзья!

 

OSA913

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

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

#20

05.08.2017 09:08:02

Некоторые макросы слегка притормаживают, проверил, оказалось все из-за процедуры «CopyData», которая выглядит таким образом:

Скрытый текст

Решил от нее избавиться и перенести ее тело в процедуру события листа «Worksheet_Change» написал код в варианте предложенном Sanja. Макросы стали работать быстрее, но некоторые значения из ячеек не хотят копироваться.

Скрытый текст

Я думаю что из-за этого например из D3 должно копироваться в M3 и также на др лист в R3. Как раз не копируются значения там где нужно их  копировать сразу в два места. Помогите сделать чтобы можно было копировать значение с одной ячейки в два места. Сейчас составлю простой пример и приложу в следующем посте.

Изменено: OSA91305.08.2017 09:11:49

 

OSA913

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

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

Вот простой пример. Значения не копируются на лист2.

 

Sanja

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

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

Напишите пожалуйста обычными словами -ЧТО, КУДА, ПРИ КАКИХ УСЛОВИЯХ должно копироваться. Потому что Ваш код неправилен и из него не понятно что Вы хотите получить на выходе

Согласие есть продукт при полном непротивлении сторон.

 

OSA913

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

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

Доброе утро) Хочу чтобы при изменении значения в любой из ячеек в A1:A4 в первом листе, значение из ячейки A1 копировалось в B1, A2 в B2, A3 в B3, A4 в B4 и так же из A1 и A2 в первом листе копировалось в A1 и A2 на втором листе.

Изменено: OSA91305.08.2017 10:09:52

 

Sanja

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

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

#24

05.08.2017 10:08:27

Код
Private Sub Worksheet_Change(ByVal Target As Range)
Application.ScreenUpdating = False
Application.EnableEvents = False
If Not Intersect(Target, Range("A1,A2,A3,A4")) Is Nothing And Target.Count = 1 Then
    On Error Resume Next
        Select Case Target.Address
        Case "$A$1"
          Set KeyCells = Range("B1")
          Set KeyCells2 = Sheets(2).Range("A1")
        Case "$A$2"
          Set KeyCells = Range("B2")
          Set KeyCells2 = Sheets(2).Range("A2")
        Case "$A$3"
            Set KeyCells = Range("B3")
        Case "$A$4"
            Set KeyCells = Range("B4")
    End Select
    KeyCells.Value = Target
    If Not KeyCells2 Is Nothing Then
        KeyCells2.Value = Target
    End If
End If
Application.EnableEvents = True
Application.ScreenUpdating = True
End Sub

Согласие есть продукт при полном непротивлении сторон.

 

OSA913

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

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

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

 

Sanja

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

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

#26

05.08.2017 12:17:45

Цитата
OSA913 написал: Не пойму почему так

Потому что

Цитата
OSA913 написал: значение в них определяется формулой

Ручной ввод и изменение значения формулой это разные вещи. ‘Повешайте’ код на событие Private Sub Worksheet_Calculate()

Согласие есть продукт при полном непротивлении сторон.

 

OSA913

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

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

Не помогло. Но в файле-примере работает.

 

OSA913

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

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

Хотя нет. В примере тоже перестало копировать когда в A1 ввел значение вручную.

 

Sanja

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

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

#29

05.08.2017 15:33:42

Вы в реальном файле формулу тоже кодом вставляете? Покажите уже пример в РЕАЛЬНОЙ СТРУКТУРЕ и что Вы в нем пытаетесь получить. Я уже просил

Цитата
Sanja написал: ЧТО, КУДА, ПРИ КАКИХ УСЛОВИЯХ должно копироваться

Что и Куда Вы объяснили, а вот про условия не хотите. Где данные изменяются вручную? Где формулой? Где формула вставляется кодом?

Согласие есть продукт при полном непротивлении сторон.

 

OSA913

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

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

#30

06.08.2017 15:09:40

В реальном файле проблема точно такая же как и в файле-примере выше. Событием «Worksheet_Change» выполняется перенос значения из ячейки A1(лист1) в ячейку B1(лист1) и в ячейку A1(лист2) когда ввожу значение в A1 в ручную — с этим проблем уже нет. Когда жму на ячейку A5(лист1), макрос задает ячейке A1(лист1) формулу =A2*A3(лист1) — с этим проблем тоже нет. Проблема — когда меняю значение в A2(лист1), в A1 меняется значение (т.к. формула), но оно не копируется в ячейку B1(лист1) и в ячейку A1(лист2). Как это поправить?

Понравилась статья? Поделить с друзьями:
  • Vba excel значение ячейки на другом листе
  • Vba excel запрос на подтверждение
  • Vba excel значение ячейки как текст
  • Vba excel запрос на обновление
  • Vba excel запрос к запросу