Домашняя страница Undo Do New Save Карта сайта Обратная связь Поиск по форуму
МИР MS EXCEL - Гость.xls

Вход

Регистрация

Напомнить пароль

 

= Мир MS Excel/Разобраться в макросе, нужна помощь. Workbook_SheetChange - Мир MS Excel

Старая форма входа
  • Страница 1 из 1
  • 1
Модератор форума: китин, _Boroda_  
Разобраться в макросе, нужна помощь. Workbook_SheetChange
SkyPro Дата: Среда, 26.06.2013, 01:36 | Сообщение № 1
Группа: Друзья
Ранг: Старожил
Сообщений: 1206
Репутация: 255 ±
Замечаний: 0% ±

2010
Доброй ночи, уважаемые форумчане.
Помогите разобраться в макросах.
Я откомментировал то, что для меня понятно, прошу поправить, если я где-либо не прав и докомментировать те строки, что мне не понятны.
Макросы отслеживания изменений на листе.
Нашел на ресурсе эесель-вба
[vba]
Код

Option Explicit

Public sValue As String ' обьявляем переменную, а какую и зачем - не понятно.
Private Sub Workbook_SheetChange(ByVal Sh As Object, ByVal Target As Range) ' срабатывание при изменении на листе
      If Sh.Name = "LOG" Then Exit Sub ' если изменения на листе LOG - выходим из макроса
      Dim sLastValue As String
      Dim lLastRow As Long
      With Sheets("LOG") ' sheets("LOG"). дальнейшие диапазоны с листа LOG.
          lLastRow = .Cells.SpecialCells(xlLastCell).Row + 1 ' назначаем переменной последнюю строку используемого диапазона листа + 1 строку
          If lLastRow = Rows.Count Then Exit Sub ' не совсем понятно, но думаю, что если значение переменной = общему кол-ву возможных строк, то выходим из макроса
          Application.ScreenUpdating = False: Application.EnableEvents = False 'отключаем обновление экрана и еще какую-то непонятную фигню
          .Cells(lLastRow, 1) = Cells(Target.Cells.Row, 1).Value
          .Cells(lLastRow, 2) = Cells(2, Target.Cells.Column).Value
          .Cells(lLastRow, 3) = Target.Value
      If Target.Count > 1 Then 'если выделено более одной ячейки то
              Dim rCell As Range, rRng As Range
              On Error Resume Next
              Set rRng = Intersect(Target, Sh.UsedRange): On Error GoTo 0 ' какое-то пересечение, но не совсем понятно
              If Not rRng Is Nothing Then ' тут тоже не понятно
                  For Each rCell In rRng ' перебор всех ячеек в диапазоне, но не понятно зачем
                      If Not IsError(Target) Then sLastValue = sLastValue & "," & rCell Else sLastValue = sLastValue & "," & "Err" ' тут вообще не понятно
                  Next rCell ' возвращаемся к перебору
                  sLastValue = Mid(sLastValue, 2) ' не понятно совсем
              Else
                  sLastValue = "" ' и тут тоже не понятно
             
      End If
          Else
              If Not IsError(Target) Then sLastValue = Target.Value Else sLastValue = "Err" ' и тут тоже не понятно
      End If
          .Cells(lLastRow, 4).NumberFormat = "@" ' и тут тоже не понятно
          .Cells(lLastRow, 4) = sLastValue ' и тут тоже не понятно
      End With
      Application.ScreenUpdating = True: Application.EnableEvents = True ' включаем то, что выключили )
End Sub

' все, что ниже не понятно зачем вообще нужно, но в источнике эти два макроса идут вместе )

Private Sub Workbook_SheetSelectionChange(ByVal Sh As Object, ByVal Target As Range)
      If Sh.Name = "LOG" Then Exit Sub
      If Target.Count > 1 Then
          Dim rCell As Range, rRng As Range
          On Error Resume Next
          Set rRng = Intersect(Target, Sh.UsedRange): On Error GoTo 0
          If rRng Is Nothing Then Exit Sub
          For Each rCell In rRng
              If Not IsError(rCell) Then sValue = sValue & "," & rCell Else sValue = sValue & "," & "Err"
          Next rCell
          sValue = Mid(sValue, 2)
      Else
          If Not IsError(Target) Then sValue = Target.Value Else sValue = "Err"
       
      End If
End Sub
[/vba]

Заранее спасибо за помощь.


skypro1111@gmail.com

Сообщение отредактировал SkyPro - Среда, 26.06.2013, 01:37
 
Ответить
СообщениеДоброй ночи, уважаемые форумчане.
Помогите разобраться в макросах.
Я откомментировал то, что для меня понятно, прошу поправить, если я где-либо не прав и докомментировать те строки, что мне не понятны.
Макросы отслеживания изменений на листе.
Нашел на ресурсе эесель-вба
[vba]
Код

Option Explicit

Public sValue As String ' обьявляем переменную, а какую и зачем - не понятно.
Private Sub Workbook_SheetChange(ByVal Sh As Object, ByVal Target As Range) ' срабатывание при изменении на листе
      If Sh.Name = "LOG" Then Exit Sub ' если изменения на листе LOG - выходим из макроса
      Dim sLastValue As String
      Dim lLastRow As Long
      With Sheets("LOG") ' sheets("LOG"). дальнейшие диапазоны с листа LOG.
          lLastRow = .Cells.SpecialCells(xlLastCell).Row + 1 ' назначаем переменной последнюю строку используемого диапазона листа + 1 строку
          If lLastRow = Rows.Count Then Exit Sub ' не совсем понятно, но думаю, что если значение переменной = общему кол-ву возможных строк, то выходим из макроса
          Application.ScreenUpdating = False: Application.EnableEvents = False 'отключаем обновление экрана и еще какую-то непонятную фигню
          .Cells(lLastRow, 1) = Cells(Target.Cells.Row, 1).Value
          .Cells(lLastRow, 2) = Cells(2, Target.Cells.Column).Value
          .Cells(lLastRow, 3) = Target.Value
      If Target.Count > 1 Then 'если выделено более одной ячейки то
              Dim rCell As Range, rRng As Range
              On Error Resume Next
              Set rRng = Intersect(Target, Sh.UsedRange): On Error GoTo 0 ' какое-то пересечение, но не совсем понятно
              If Not rRng Is Nothing Then ' тут тоже не понятно
                  For Each rCell In rRng ' перебор всех ячеек в диапазоне, но не понятно зачем
                      If Not IsError(Target) Then sLastValue = sLastValue & "," & rCell Else sLastValue = sLastValue & "," & "Err" ' тут вообще не понятно
                  Next rCell ' возвращаемся к перебору
                  sLastValue = Mid(sLastValue, 2) ' не понятно совсем
              Else
                  sLastValue = "" ' и тут тоже не понятно
             
      End If
          Else
              If Not IsError(Target) Then sLastValue = Target.Value Else sLastValue = "Err" ' и тут тоже не понятно
      End If
          .Cells(lLastRow, 4).NumberFormat = "@" ' и тут тоже не понятно
          .Cells(lLastRow, 4) = sLastValue ' и тут тоже не понятно
      End With
      Application.ScreenUpdating = True: Application.EnableEvents = True ' включаем то, что выключили )
End Sub

' все, что ниже не понятно зачем вообще нужно, но в источнике эти два макроса идут вместе )

Private Sub Workbook_SheetSelectionChange(ByVal Sh As Object, ByVal Target As Range)
      If Sh.Name = "LOG" Then Exit Sub
      If Target.Count > 1 Then
          Dim rCell As Range, rRng As Range
          On Error Resume Next
          Set rRng = Intersect(Target, Sh.UsedRange): On Error GoTo 0
          If rRng Is Nothing Then Exit Sub
          For Each rCell In rRng
              If Not IsError(rCell) Then sValue = sValue & "," & rCell Else sValue = sValue & "," & "Err"
          Next rCell
          sValue = Mid(sValue, 2)
      Else
          If Not IsError(Target) Then sValue = Target.Value Else sValue = "Err"
       
      End If
End Sub
[/vba]

Заранее спасибо за помощь.

Автор - SkyPro
Дата добавления - 26.06.2013 в 01:36
Alex_ST Дата: Среда, 26.06.2013, 22:41 | Сообщение № 2
Группа: Друзья
Ранг: Участник клуба
Сообщений: 3214
Репутация: 615 ±
Замечаний: 0% ±

2003
Честно говоря, ковырять чужой код даже не зная что он должен делать, лень.
А где Вы его взяли? Автора спросить нельзя?
Судя по стилю программирования и именам переменных - это кто-то из местных или с Планеты.
Код, похоже, должен вести какой-то лог изменений на листах книги... Но какой-то странный - без указания листов, на которых происходили изменения, а только адресов изменяемых ячеек или просто специфический?
Размещаться код явно должен в модуле ЭтаКнига.
Но тогда строки [vba]
Код
        .Cells(lLastRow, 1) = Cells(Target.Cells.Row, 1).Value
          .Cells(lLastRow, 2) = Cells(2, Target.Cells.Column).Value
[/vba] ИМХО не совсем корректны, т.к. "родитель" - не лист и ячеек не имеет. Поэтому возможно неоднозначное срабатывание.
[vba]
Код
Application.EnableEvents = False
[/vba] - отключение реакции приложения на события.
[vba]
Код
On Error Resume Next
              Set rRng = Intersect(Target, Sh.UsedRange): On Error GoTo 0
[/vba] вообще не вижу смысла включать обработчик ошибок, производить действие, которое не может вызвать ошибку, а потом отключать обработчик.

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



С уважением,
Алексей
MS Excel 2003 - the best!!!


Сообщение отредактировал Alex_ST - Среда, 26.06.2013, 22:42
 
Ответить
СообщениеЧестно говоря, ковырять чужой код даже не зная что он должен делать, лень.
А где Вы его взяли? Автора спросить нельзя?
Судя по стилю программирования и именам переменных - это кто-то из местных или с Планеты.
Код, похоже, должен вести какой-то лог изменений на листах книги... Но какой-то странный - без указания листов, на которых происходили изменения, а только адресов изменяемых ячеек или просто специфический?
Размещаться код явно должен в модуле ЭтаКнига.
Но тогда строки [vba]
Код
        .Cells(lLastRow, 1) = Cells(Target.Cells.Row, 1).Value
          .Cells(lLastRow, 2) = Cells(2, Target.Cells.Column).Value
[/vba] ИМХО не совсем корректны, т.к. "родитель" - не лист и ячеек не имеет. Поэтому возможно неоднозначное срабатывание.
[vba]
Код
Application.EnableEvents = False
[/vba] - отключение реакции приложения на события.
[vba]
Код
On Error Resume Next
              Set rRng = Intersect(Target, Sh.UsedRange): On Error GoTo 0
[/vba] вообще не вижу смысла включать обработчик ошибок, производить действие, которое не может вызвать ошибку, а потом отключать обработчик.

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

Автор - Alex_ST
Дата добавления - 26.06.2013 в 22:41
Serge_007 Дата: Среда, 26.06.2013, 22:45 | Сообщение № 3
Группа: Админы
Ранг: Местный житель
Сообщений: 16475
Репутация: 2749 ±
Замечаний: ±

Excel 2016
Цитата (SkyPro)
Нашел на ресурсе эесель-вба
Т.е. вопрос Диме (The_Prist)


ЮMoney:41001419691823 | WMR:126292472390
 
Ответить
Сообщение
Цитата (SkyPro)
Нашел на ресурсе эесель-вба
Т.е. вопрос Диме (The_Prist)

Автор - Serge_007
Дата добавления - 26.06.2013 в 22:45
Alex_ST Дата: Среда, 26.06.2013, 22:49 | Сообщение № 4
Группа: Друзья
Ранг: Участник клуба
Сообщений: 3214
Репутация: 615 ±
Замечаний: 0% ±

2003
Да, похоже на Димин стиль.
Я даже в посте сначала про это написал и ссылку на его "Что умеет..." дал.
Но потом посмотрел внимательно на код, увидел ляпы и решил, что это кто-то из учеников мастера ваял, а потому ссылку стёр.



С уважением,
Алексей
MS Excel 2003 - the best!!!
 
Ответить
СообщениеДа, похоже на Димин стиль.
Я даже в посте сначала про это написал и ссылку на его "Что умеет..." дал.
Но потом посмотрел внимательно на код, увидел ляпы и решил, что это кто-то из учеников мастера ваял, а потому ссылку стёр.

Автор - Alex_ST
Дата добавления - 26.06.2013 в 22:49
Саня Дата: Среда, 26.06.2013, 22:54 | Сообщение № 5
Группа: Друзья
Ранг: Ветеран
Сообщений: 1068
Репутация: 560 ±
Замечаний: 0% ±

XL 2016
Цитата (Alex_ST)
.Cells(lLastRow, 1) = ...

Леша, что ты?
Там же вверху
[vba]
Код
With Sheets("LOG")
[/vba]

Цитата (Alex_ST)
On Error Resume ....

здесь да, согласен Intersect единственно тогда "умирает", когда идет попытка перехлестнуть диапазоны с разных листов/книг
здесь заведомо такое невозможно
 
Ответить
Сообщение
Цитата (Alex_ST)
.Cells(lLastRow, 1) = ...

Леша, что ты?
Там же вверху
[vba]
Код
With Sheets("LOG")
[/vba]

Цитата (Alex_ST)
On Error Resume ....

здесь да, согласен Intersect единственно тогда "умирает", когда идет попытка перехлестнуть диапазоны с разных листов/книг
здесь заведомо такое невозможно

Автор - Саня
Дата добавления - 26.06.2013 в 22:54
Alex_ST Дата: Среда, 26.06.2013, 23:00 | Сообщение № 6
Группа: Друзья
Ранг: Участник клуба
Сообщений: 3214
Репутация: 615 ±
Замечаний: 0% ±

2003
Покопался у Димы и нашёл то, что было искалечено у топик-стартера - Ведение журнала сделанных в книге изменений

Саня, я не про это, а про [vba]
Код
= Cells(Target.Cells.Row, 1).Value
[/vba]
Запись просто Cells - это просто сокращение Me.Cells, а Ме в случае модуля ЭтаКнига не имеет коллекции Cеlls



С уважением,
Алексей
MS Excel 2003 - the best!!!


Сообщение отредактировал Alex_ST - Среда, 26.06.2013, 23:03
 
Ответить
СообщениеПокопался у Димы и нашёл то, что было искалечено у топик-стартера - Ведение журнала сделанных в книге изменений

Саня, я не про это, а про [vba]
Код
= Cells(Target.Cells.Row, 1).Value
[/vba]
Запись просто Cells - это просто сокращение Me.Cells, а Ме в случае модуля ЭтаКнига не имеет коллекции Cеlls

Автор - Alex_ST
Дата добавления - 26.06.2013 в 23:00
Саня Дата: Среда, 26.06.2013, 23:32 | Сообщение № 7
Группа: Друзья
Ранг: Ветеран
Сообщений: 1068
Репутация: 560 ±
Замечаний: 0% ±

XL 2016
Цитата (Alex_ST)
Запись просто Cells - это просто сокращение Me.Cells,

считаю, что это выполняется для модуля листа
а для этого случая = Activesheet.Cells(....

хотя могу ошибаться, проверять-то лень, поэтому можно и поголословить biggrin
 
Ответить
Сообщение
Цитата (Alex_ST)
Запись просто Cells - это просто сокращение Me.Cells,

считаю, что это выполняется для модуля листа
а для этого случая = Activesheet.Cells(....

хотя могу ошибаться, проверять-то лень, поэтому можно и поголословить biggrin

Автор - Саня
Дата добавления - 26.06.2013 в 23:32
SkyPro Дата: Среда, 26.06.2013, 23:51 | Сообщение № 8
Группа: Друзья
Ранг: Старожил
Сообщений: 1206
Репутация: 255 ±
Замечаний: 0% ±

2010
[vba]
Код
        .Cells(lLastRow, 1) = Cells(Target.Cells.Row, 1).Value
            .Cells(lLastRow, 2) = Cells(2, Target.Cells.Column).Value
[/vba]
Эти две строки я добавил =\ (видимо криво)
но другой вариант добавить название столбца (шапки листа) и значения из первого столбца (для идентификации строки в которой были изменения) я не придумал.

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

PS: Да, это макрос для модуля листа. ПРошу прощения, что не указал это при создании темы.


skypro1111@gmail.com

Сообщение отредактировал SkyPro - Четверг, 27.06.2013, 00:05
 
Ответить
Сообщение[vba]
Код
        .Cells(lLastRow, 1) = Cells(Target.Cells.Row, 1).Value
            .Cells(lLastRow, 2) = Cells(2, Target.Cells.Column).Value
[/vba]
Эти две строки я добавил =\ (видимо криво)
но другой вариант добавить название столбца (шапки листа) и значения из первого столбца (для идентификации строки в которой были изменения) я не придумал.

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

PS: Да, это макрос для модуля листа. ПРошу прощения, что не указал это при создании темы.

Автор - SkyPro
Дата добавления - 26.06.2013 в 23:51
Alex_ST Дата: Четверг, 27.06.2013, 09:56 | Сообщение № 9
Группа: Друзья
Ранг: Участник клуба
Сообщений: 3214
Репутация: 615 ±
Замечаний: 0% ±

2003
Саня,
посмотри внимательно на названия и аргументы обработчиков событий - это ЯВНО обработчики событий не ЛИСТА, а КНИГИ. И если разместить такие коды в модуле листа, то события просто не возникнут biggrin (хотя, чем чёрт не шутит - просто никогда даже в голову не приходило их туда попробовать засунуть - а вдруг заработают?)

Цитата (SkyPro)
это макрос для модуля листа
что-то сильно сомневаюсь, что события книги будут обрабатываться в модуле листа...
А что Вам мешает разместить эти коды правильно - в модуле ЭтаКнига - и чуть подправить код:
вместо Cells писать Sh.Cells?
И почему бы Вам не задавать вопросы по функционированию и доработке макроса там, где Вы его взяли - у Дмитрия (The_Prist) в теме Ведение журнала сделанных в книге изменений или на его же Форуме?

Поймите, странность и некорректность ситуации.
Ведь мы же, Excel-маны biggrin , все общаемся на нескольких форумах одновременно и друг друга знаем достаточно хорошо.
Ведь не с проста же я сразу сказал, что стиль программирования мне кажется знакомым и быстро нашёл, откуда "ноги растут".
А Вы на другом сайте взяли готовый код, написанный нашим другом, но почему-то скрываете первоисточник.
Сразу возникает законный вопрос: "Вы с Димой что-то не поделили?"
Тогда извините, но он наш друг и помогать Вам тут мало кто захочет.
А потом Вы как-то сами доработали код, не объясняя, что в результате хотели получить.
И теперь пытаетесь ЗДЕСЬ разобраться, как "исправленный" Вами код работает. Мы гадать должны о Ваших задумках?



С уважением,
Алексей
MS Excel 2003 - the best!!!
 
Ответить
СообщениеСаня,
посмотри внимательно на названия и аргументы обработчиков событий - это ЯВНО обработчики событий не ЛИСТА, а КНИГИ. И если разместить такие коды в модуле листа, то события просто не возникнут biggrin (хотя, чем чёрт не шутит - просто никогда даже в голову не приходило их туда попробовать засунуть - а вдруг заработают?)

Цитата (SkyPro)
это макрос для модуля листа
что-то сильно сомневаюсь, что события книги будут обрабатываться в модуле листа...
А что Вам мешает разместить эти коды правильно - в модуле ЭтаКнига - и чуть подправить код:
вместо Cells писать Sh.Cells?
И почему бы Вам не задавать вопросы по функционированию и доработке макроса там, где Вы его взяли - у Дмитрия (The_Prist) в теме Ведение журнала сделанных в книге изменений или на его же Форуме?

Поймите, странность и некорректность ситуации.
Ведь мы же, Excel-маны biggrin , все общаемся на нескольких форумах одновременно и друг друга знаем достаточно хорошо.
Ведь не с проста же я сразу сказал, что стиль программирования мне кажется знакомым и быстро нашёл, откуда "ноги растут".
А Вы на другом сайте взяли готовый код, написанный нашим другом, но почему-то скрываете первоисточник.
Сразу возникает законный вопрос: "Вы с Димой что-то не поделили?"
Тогда извините, но он наш друг и помогать Вам тут мало кто захочет.
А потом Вы как-то сами доработали код, не объясняя, что в результате хотели получить.
И теперь пытаетесь ЗДЕСЬ разобраться, как "исправленный" Вами код работает. Мы гадать должны о Ваших задумках?

Автор - Alex_ST
Дата добавления - 27.06.2013 в 09:56
Саня Дата: Четверг, 27.06.2013, 11:41 | Сообщение № 10
Группа: Друзья
Ранг: Ветеран
Сообщений: 1068
Репутация: 560 ±
Замечаний: 0% ±

XL 2016
Цитата (Alex_ST)
посмотри внимательно на названия и аргументы обработчиков событий

Зачем? Я прекрасно различаю эти вещи:
[vba]
Код
Private Sub Worksheet_Change(ByVal Target As Range)
Private Sub Worksheet_SelectionChange(ByVal Target As Range)

Private Sub Workbook_SheetChange(ByVal Sh As Object, ByVal Target As Range)
Private Sub Workbook_SheetSelectionChange(ByVal Sh As Object, ByVal Target As Range)
[/vba]

Цитата (Alex_ST)
И если разместить такие коды в модуле листа, то события просто не возникнут biggrin (хотя, чем чёрт не шутит - просто никогда даже в голову не приходило их туда попробовать засунуть - а вдруг заработают?)

не заработают, не сомневайся - это будут просто приватные процедуры/методы класса

у меня есть подозрение, что происходит все след. образом:
1) модуль листа.
Cells - есть свойство класса Worksheet, поэтому компилятор воспринимает это как Me.Cells

2) модуль книги
Cells - несуществующее свойство объекта Workbook, поэтому компилятор ищет в global-объектах

работает именно так.

К сообщению приложен файл: 4627015.jpg (65.9 Kb)
 
Ответить
Сообщение
Цитата (Alex_ST)
посмотри внимательно на названия и аргументы обработчиков событий

Зачем? Я прекрасно различаю эти вещи:
[vba]
Код
Private Sub Worksheet_Change(ByVal Target As Range)
Private Sub Worksheet_SelectionChange(ByVal Target As Range)

Private Sub Workbook_SheetChange(ByVal Sh As Object, ByVal Target As Range)
Private Sub Workbook_SheetSelectionChange(ByVal Sh As Object, ByVal Target As Range)
[/vba]

Цитата (Alex_ST)
И если разместить такие коды в модуле листа, то события просто не возникнут biggrin (хотя, чем чёрт не шутит - просто никогда даже в голову не приходило их туда попробовать засунуть - а вдруг заработают?)

не заработают, не сомневайся - это будут просто приватные процедуры/методы класса

у меня есть подозрение, что происходит все след. образом:
1) модуль листа.
Cells - есть свойство класса Worksheet, поэтому компилятор воспринимает это как Me.Cells

2) модуль книги
Cells - несуществующее свойство объекта Workbook, поэтому компилятор ищет в global-объектах

работает именно так.


Автор - Саня
Дата добавления - 27.06.2013 в 11:41
Alex_ST Дата: Четверг, 27.06.2013, 11:45 | Сообщение № 11
Группа: Друзья
Ранг: Участник клуба
Сообщений: 3214
Репутация: 615 ±
Замечаний: 0% ±

2003
И с какого листа он возьмёт коллекцию Cells? Наверное, с ActiveSheet?

Цитата (Саня)
а для этого случая = Activesheet.Cells(....



С уважением,
Алексей
MS Excel 2003 - the best!!!
 
Ответить
СообщениеИ с какого листа он возьмёт коллекцию Cells? Наверное, с ActiveSheet?

Цитата (Саня)
а для этого случая = Activesheet.Cells(....

Автор - Alex_ST
Дата добавления - 27.06.2013 в 11:45
SkyPro Дата: Четверг, 27.06.2013, 21:24 | Сообщение № 12
Группа: Друзья
Ранг: Старожил
Сообщений: 1206
Репутация: 255 ±
Замечаний: 0% ±

2010
Цитата (Alex_ST)
Поймите, странность и некорректность ситуации. Ведь мы же, Excel-маны , все общаемся на нескольких форумах одновременно и друг друга знаем достаточно хорошо. Ведь не с проста же я сразу сказал, что стиль программирования мне кажется знакомым и быстро нашёл, откуда "ноги растут". А Вы на другом сайте взяли готовый код, написанный нашим другом, но почему-то скрываете первоисточник.

Я прекрасно понимаю, что вы, гуру экселя (это не сарказм), друг друга знаете. И я источник указал в первом посте
Цитата
Макросы отслеживания изменений на листе.
Нашел на ресурсе эесель-вба
(просто думал, что ссылку на другой ресурс могут приять за рекламу).

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

Код изменен только в тех строках, где записываются значения ячеек листа "LOG". Тоесть в строках, которые на выполнение самого макроса не должны влиять.

ЗЫ:
Уважаемые, если я нарушил правила форума, или чем-либо вас обидел, то прошу закрыть и забыть эту тему (правда вы и так своей дискусией подкинули мне пищу для ума, за что отдельное спасибо).
Я просто попросил помощи.

ЗЫЗЫ:
Простите еще и мою невнимательность.. Да, действительно это код модуля книги, как и указано в источнике.


skypro1111@gmail.com

Сообщение отредактировал SkyPro - Четверг, 27.06.2013, 21:28
 
Ответить
Сообщение
Цитата (Alex_ST)
Поймите, странность и некорректность ситуации. Ведь мы же, Excel-маны , все общаемся на нескольких форумах одновременно и друг друга знаем достаточно хорошо. Ведь не с проста же я сразу сказал, что стиль программирования мне кажется знакомым и быстро нашёл, откуда "ноги растут". А Вы на другом сайте взяли готовый код, написанный нашим другом, но почему-то скрываете первоисточник.

Я прекрасно понимаю, что вы, гуру экселя (это не сарказм), друг друга знаете. И я источник указал в первом посте
Цитата
Макросы отслеживания изменений на листе.
Нашел на ресурсе эесель-вба
(просто думал, что ссылку на другой ресурс могут приять за рекламу).

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

Код изменен только в тех строках, где записываются значения ячеек листа "LOG". Тоесть в строках, которые на выполнение самого макроса не должны влиять.

ЗЫ:
Уважаемые, если я нарушил правила форума, или чем-либо вас обидел, то прошу закрыть и забыть эту тему (правда вы и так своей дискусией подкинули мне пищу для ума, за что отдельное спасибо).
Я просто попросил помощи.

ЗЫЗЫ:
Простите еще и мою невнимательность.. Да, действительно это код модуля книги, как и указано в источнике.

Автор - SkyPro
Дата добавления - 27.06.2013 в 21:24
Alex_ST Дата: Четверг, 27.06.2013, 21:47 | Сообщение № 13
Группа: Друзья
Ранг: Участник клуба
Сообщений: 3214
Репутация: 615 ±
Замечаний: 0% ±

2003
Ну, даже странно...
Вы форум Димы (The_Prist) пролистывали?
Это там-то недостаточно адекватных, умных и, главное, ТЕРПЕЛИВЫХ людей? Да Дима - один из первой десятки самых знающих и умеющих разъяснять гуру!
Тут очень многие нынешние знатоки познавали азы по его программам и под его руководством.
Не даром же я говорил о знакомом стиле программирования и наименования переменных. Это его стиль, который теперь уже переняли многие. И я сам по его программам учился.
На самом деле Вы ничего не нарушили и, кажется, никого не обидели, но просто корректнее всего было бы обратиться к Диме.

Ну а если всё-таки хотите получить помощь здесь, то излагайте словами алгоритм:
что и где есть (структура книги), что, где и в каком виде хотите получить и по каким событиям в книге.
Прилагайте файл-пример со своими наработками (в соответствии с Правилами форума).
Тогда будем разбираться, что и почему не работает.



С уважением,
Алексей
MS Excel 2003 - the best!!!
 
Ответить
СообщениеНу, даже странно...
Вы форум Димы (The_Prist) пролистывали?
Это там-то недостаточно адекватных, умных и, главное, ТЕРПЕЛИВЫХ людей? Да Дима - один из первой десятки самых знающих и умеющих разъяснять гуру!
Тут очень многие нынешние знатоки познавали азы по его программам и под его руководством.
Не даром же я говорил о знакомом стиле программирования и наименования переменных. Это его стиль, который теперь уже переняли многие. И я сам по его программам учился.
На самом деле Вы ничего не нарушили и, кажется, никого не обидели, но просто корректнее всего было бы обратиться к Диме.

Ну а если всё-таки хотите получить помощь здесь, то излагайте словами алгоритм:
что и где есть (структура книги), что, где и в каком виде хотите получить и по каким событиям в книге.
Прилагайте файл-пример со своими наработками (в соответствии с Правилами форума).
Тогда будем разбираться, что и почему не работает.

Автор - Alex_ST
Дата добавления - 27.06.2013 в 21:47
SkyPro Дата: Пятница, 28.06.2013, 01:12 | Сообщение № 14
Группа: Друзья
Ранг: Старожил
Сообщений: 1206
Репутация: 255 ±
Замечаний: 0% ±

2010
В файле есть лист "1" и лист "log".
Необходимо отслеживать изменения на листе 1 и записывать произошедшие изменения на лист "log".
В зафиксированных данных должно быть значение ячейки, которое было до изменения, после изменения, значение из столбца 1 (ID) и соответствующей измененной ячейке строки, и значение из строки 1 (шапка) и соответствующего измененной ячейке столбца.
Пример файла и первичный вариант макроса (делал по примеру макросов с excel-vba.ru):
[vba]
Код

Option Explicit ' обьясните что эта фигня делает <img src="http://s5.ucoz.net/sm/1/smile.gif" border="0" align="absmiddle" alt="smile" />
Public bChange As String ' обьявляем переменную для всех макросов  

Private Sub Workbook_SheetChange(ByVal Sh As Object, ByVal Target As Range) ' срабатывание макроса при любом изменении на листе (кроме автопересчета формул)
If Sh.Name = "log" Then Exit Sub ' если активен лист log -выходим из макроса
Dim lrow As Long

lrow = Sheets("log").Cells.SpecialCells(xlLastCell).Row + 1 ' устанавливаем значение переменной (последняя активная строка диапазона + 1)

Application.ScreenUpdating = False: Application.EnableEvents = False ' отключаем обновление экрана и (еле допер зачем это) обработку событий, что бы не установилось новое значение bChange до записи на лист log

Sheets("log").Cells(lrow, 1) = Cells(Target.Cells.Row, 1).Value ' записываем значение из столбца ID и соответствующей измененной ячейки строки
Sheets("log").Cells(lrow, 2) = Cells(1, Target.Cells.Column).Value ' записываем значение из первой строки и соответствующего измененной ячейки столбца (шапка)
Sheets("log").Cells(lrow, 3) = bChange ' записываем значение ячейки до изменения (вот зачем был следующий макрос)
Sheets("log").Cells(lrow, 4) = Target.Value ' записываем измененное значение ячейки

Application.ScreenUpdating = True: Application.EnableEvents = True ' включаем обновление экрана и обработку событий

End Sub

Private Sub Workbook_SheetSelectionChange(ByVal Sh As Object, ByVal Target As Range) ' срабатывание макроса на выбор ячейки\диапазона
If Sh.Name = "log" Then Exit Sub ' если активен лист log -выходим из макроса
If Target.Count > 1 Then Exit Sub ' пока отключаем выбор диапазона, нужно подумать.
bChange = Target.Value ' назначаем глобальной (если не правильное название - поправьте) переменной значение выбраного диапазона
End Sub

[/vba]
Макрос модуля книги.
Где я ошибся?
ЗЫ: в процессе проверка на "ложные изменения" и выбор диапазона.
К сообщению приложен файл: primer.xlsx (11.6 Kb)


skypro1111@gmail.com

Сообщение отредактировал SkyPro - Пятница, 28.06.2013, 01:27
 
Ответить
СообщениеВ файле есть лист "1" и лист "log".
Необходимо отслеживать изменения на листе 1 и записывать произошедшие изменения на лист "log".
В зафиксированных данных должно быть значение ячейки, которое было до изменения, после изменения, значение из столбца 1 (ID) и соответствующей измененной ячейке строки, и значение из строки 1 (шапка) и соответствующего измененной ячейке столбца.
Пример файла и первичный вариант макроса (делал по примеру макросов с excel-vba.ru):
[vba]
Код

Option Explicit ' обьясните что эта фигня делает <img src="http://s5.ucoz.net/sm/1/smile.gif" border="0" align="absmiddle" alt="smile" />
Public bChange As String ' обьявляем переменную для всех макросов  

Private Sub Workbook_SheetChange(ByVal Sh As Object, ByVal Target As Range) ' срабатывание макроса при любом изменении на листе (кроме автопересчета формул)
If Sh.Name = "log" Then Exit Sub ' если активен лист log -выходим из макроса
Dim lrow As Long

lrow = Sheets("log").Cells.SpecialCells(xlLastCell).Row + 1 ' устанавливаем значение переменной (последняя активная строка диапазона + 1)

Application.ScreenUpdating = False: Application.EnableEvents = False ' отключаем обновление экрана и (еле допер зачем это) обработку событий, что бы не установилось новое значение bChange до записи на лист log

Sheets("log").Cells(lrow, 1) = Cells(Target.Cells.Row, 1).Value ' записываем значение из столбца ID и соответствующей измененной ячейки строки
Sheets("log").Cells(lrow, 2) = Cells(1, Target.Cells.Column).Value ' записываем значение из первой строки и соответствующего измененной ячейки столбца (шапка)
Sheets("log").Cells(lrow, 3) = bChange ' записываем значение ячейки до изменения (вот зачем был следующий макрос)
Sheets("log").Cells(lrow, 4) = Target.Value ' записываем измененное значение ячейки

Application.ScreenUpdating = True: Application.EnableEvents = True ' включаем обновление экрана и обработку событий

End Sub

Private Sub Workbook_SheetSelectionChange(ByVal Sh As Object, ByVal Target As Range) ' срабатывание макроса на выбор ячейки\диапазона
If Sh.Name = "log" Then Exit Sub ' если активен лист log -выходим из макроса
If Target.Count > 1 Then Exit Sub ' пока отключаем выбор диапазона, нужно подумать.
bChange = Target.Value ' назначаем глобальной (если не правильное название - поправьте) переменной значение выбраного диапазона
End Sub

[/vba]
Макрос модуля книги.
Где я ошибся?
ЗЫ: в процессе проверка на "ложные изменения" и выбор диапазона.

Автор - SkyPro
Дата добавления - 28.06.2013 в 01:12
Alex_ST Дата: Пятница, 28.06.2013, 09:24 | Сообщение № 15
Группа: Друзья
Ранг: Участник клуба
Сообщений: 3214
Репутация: 615 ±
Замечаний: 0% ±

2003
А в чём проблема? У Вас всё работает.
Ну разве что чуть "причесать" для красоты и откомментировать примерно так:[vba]
Код
Option Explicit   ' команда компилятору требовать объявления переменные - это не обязательно, но желательно для упрощения отладки. И вообще является признаком хорошего тона в программировании <img src="http://s5.ucoz.net/sm/1/smile.gif" border="0" align="absmiddle" alt="smile" />
Dim vPrevious_Value  ' переменная, в которую будут записываться предыдущие перед изменением значения ячеек

Private Sub Workbook_SheetChange(ByVal Sh As Object, ByVal Target As Range)  ' процедура, автоматически вызываемая приложением при любом изменении на любом листе (кроме автопересчета формул)
      If Sh.Name = "log" Then Exit Sub   ' если активен лист log, выходим
      Dim lRow As Long   ' переменная для хранения номера первой пустой строки листа "log"
      lRow = Sheets("log").Cells.SpecialCells(xlLastCell).Row + 1   '  находим номер первой пустой строки листа "log" чтобы в неё записывать данные
      Application.ScreenUpdating = False: Application.EnableEvents = False   ' отключаем обновление экрана (чтобы не моргал) и обработку событий (чтобы не реагировало на запись на лист log и не было зацикливания)
    With Sheets("log") ' на листе "log" …
       .Cells(lRow, 1) = Sh.Cells(Target.Cells.Row, 1).Value   ' … в строке lRow в ячейку столбца 1 записываем значение из ячейки столбца 1 - ID строки
       .Cells(lRow, 2) = Sh.Cells(1, Target.Cells.Column).Value   ' … в строке lRow в ячейку столбца 2 записываем значение из ячейки строки 1 - шапка
       .Cells(lRow, 3) = vPrevious_Value   '  … в строке lRow в ячейку столбца 3 записываем значение ячейки до изменения
       .Cells(lRow, 4) = Target.Value   '  … в строке lRow в ячейку столбца 4 записываем новое значение ячейки
    End With
      Application.ScreenUpdating = True: Application.EnableEvents = True   ' включаем обновление экрана и обработку событий
End Sub

Private Sub Workbook_SheetSelectionChange(ByVal Sh As Object, ByVal Target As Range)   ' процедура, автоматически вызываемая приложением при КАЖДОМ изменении выбранного диапазона
      If Sh.Name = "log" Then Exit Sub   ' если активен лист log, выходим
      If Target.Count > 1 Then Exit Sub   ' если выбрано больше одной ячейки, выходим
      vPrevious_Value = Target.Value   ' запоминаем значение ячейки до изменения
End Sub
[/vba]



С уважением,
Алексей
MS Excel 2003 - the best!!!


Сообщение отредактировал Alex_ST - Пятница, 28.06.2013, 09:26
 
Ответить
СообщениеА в чём проблема? У Вас всё работает.
Ну разве что чуть "причесать" для красоты и откомментировать примерно так:[vba]
Код
Option Explicit   ' команда компилятору требовать объявления переменные - это не обязательно, но желательно для упрощения отладки. И вообще является признаком хорошего тона в программировании <img src="http://s5.ucoz.net/sm/1/smile.gif" border="0" align="absmiddle" alt="smile" />
Dim vPrevious_Value  ' переменная, в которую будут записываться предыдущие перед изменением значения ячеек

Private Sub Workbook_SheetChange(ByVal Sh As Object, ByVal Target As Range)  ' процедура, автоматически вызываемая приложением при любом изменении на любом листе (кроме автопересчета формул)
      If Sh.Name = "log" Then Exit Sub   ' если активен лист log, выходим
      Dim lRow As Long   ' переменная для хранения номера первой пустой строки листа "log"
      lRow = Sheets("log").Cells.SpecialCells(xlLastCell).Row + 1   '  находим номер первой пустой строки листа "log" чтобы в неё записывать данные
      Application.ScreenUpdating = False: Application.EnableEvents = False   ' отключаем обновление экрана (чтобы не моргал) и обработку событий (чтобы не реагировало на запись на лист log и не было зацикливания)
    With Sheets("log") ' на листе "log" …
       .Cells(lRow, 1) = Sh.Cells(Target.Cells.Row, 1).Value   ' … в строке lRow в ячейку столбца 1 записываем значение из ячейки столбца 1 - ID строки
       .Cells(lRow, 2) = Sh.Cells(1, Target.Cells.Column).Value   ' … в строке lRow в ячейку столбца 2 записываем значение из ячейки строки 1 - шапка
       .Cells(lRow, 3) = vPrevious_Value   '  … в строке lRow в ячейку столбца 3 записываем значение ячейки до изменения
       .Cells(lRow, 4) = Target.Value   '  … в строке lRow в ячейку столбца 4 записываем новое значение ячейки
    End With
      Application.ScreenUpdating = True: Application.EnableEvents = True   ' включаем обновление экрана и обработку событий
End Sub

Private Sub Workbook_SheetSelectionChange(ByVal Sh As Object, ByVal Target As Range)   ' процедура, автоматически вызываемая приложением при КАЖДОМ изменении выбранного диапазона
      If Sh.Name = "log" Then Exit Sub   ' если активен лист log, выходим
      If Target.Count > 1 Then Exit Sub   ' если выбрано больше одной ячейки, выходим
      vPrevious_Value = Target.Value   ' запоминаем значение ячейки до изменения
End Sub
[/vba]

Автор - Alex_ST
Дата добавления - 28.06.2013 в 09:24
KuklP Дата: Пятница, 28.06.2013, 10:40 | Сообщение № 16
Группа: Проверенные
Ранг: Старожил
Сообщений: 2369
Репутация: 486 ±
Замечаний: 0% ±

2003-2010
Цитата (SkyPro)
Обратился сюда, а не на форум "источника", так как знаю, что среди здешних есть достаточно адекватных и очень умных людей, которые смогут помочь, а что делается на том форуме - не вкурсе.
- отвратительно!

Цитата (Alex_ST)
Вы форум Димы (The_Prist) пролистывали?
Леш, ну это даже в комментах не нуждается, нафиг было продолжать? Дальнейшее обсуждение, плиз, в личку.


Ну с НДС и мы чего-то стoим! kuklp60@gmail.com
WM Z206653985942, R334086032478, U238399322728
 
Ответить
Сообщение
Цитата (SkyPro)
Обратился сюда, а не на форум "источника", так как знаю, что среди здешних есть достаточно адекватных и очень умных людей, которые смогут помочь, а что делается на том форуме - не вкурсе.
- отвратительно!

Цитата (Alex_ST)
Вы форум Димы (The_Prist) пролистывали?
Леш, ну это даже в комментах не нуждается, нафиг было продолжать? Дальнейшее обсуждение, плиз, в личку.

Автор - KuklP
Дата добавления - 28.06.2013 в 10:40
  • Страница 1 из 1
  • 1
Поиск:

Яндекс.Метрика Яндекс цитирования
© 2010-2024 · Дизайн: MichaelCH · Хостинг от uCoz · При использовании материалов сайта, ссылка на www.excelworld.ru обязательна!