Как защитить ячейку при наступлении очередного месяца (даты)? Есть пустая незащищённая ячейка (P12). Вносим данные (000020). При наступлении очередного месяца (окт.2017) ячейка должна защититься.
Как защитить ячейку при наступлении очередного месяца (даты)? Есть пустая незащищённая ячейка (P12). Вносим данные (000020). При наступлении очередного месяца (окт.2017) ячейка должна защититься.Gold_Barsik
Внесли данные. Через два дня изменили. От какой даты считать месяц? Это пища для размышлений.
Если сами пишете, то алгоритм примерно такой. По событию листа (изменение ячейки) на другой лист в такую же ячейку вносится дата, либо дата-время действия. По какому-нибудь другому событию (например, открытие книги) запускается макрос, защищающий ячейки, у которых дата соответствует Вашему условию.
Внесли данные. Через два дня изменили. От какой даты считать месяц? Это пища для размышлений.
Если сами пишете, то алгоритм примерно такой. По событию листа (изменение ячейки) на другой лист в такую же ячейку вносится дата, либо дата-время действия. По какому-нибудь другому событию (например, открытие книги) запускается макрос, защищающий ячейки, у которых дата соответствует Вашему условию.Perfect2You
Внёс, изменил, изменил, но если наступил новый МЕСЯЦ в ячейке A1, ячейка защищается. Если МЕСЯЦ в ячейке A1 изменить на ранний, то ячейка становится незащищённая. Сам писать пока не научился, потому и спрашиваю. А далее "По событию" я ничего не понял. Можно ли поподробнее и в примере (в картинках)?
Внёс, изменил, изменил, но если наступил новый МЕСЯЦ в ячейке A1, ячейка защищается. Если МЕСЯЦ в ячейке A1 изменить на ранний, то ячейка становится незащищённая. Сам писать пока не научился, потому и спрашиваю. А далее "По событию" я ничего не понял. Можно ли поподробнее и в примере (в картинках)?Gold_Barsik
Сообщение отредактировал Gold_Barsik - Пятница, 29.09.2017, 16:20
Sub BlokYa() Dim d_ As Range c1_ = Cells(4, Columns.Count).End(1).Column c0_ = 4 r0_ = 4 r1_ = Cells(Rows.Count, c0_ - 1).End(3).Row For Each d_ In Cells(r0_, c0_).Resize(1, c1_ - c0_ + 1) If IsDate(d_) Then Cells(r0_ - 1, d_.Column).Resize(r1_ - r0_ + 2, 6).Locked = DateAdd("m", 1, d_) < Date End If Next d_ End Sub
Private Sub Worksheet_Change(ByVal Target As Range) c1_ = Cells(4, Columns.Count).End(1).Column c0_ = 4 r0_ = 4 If Not Intersect(Target, Cells(r0_, c0_).Resize(1, c1_ - c0_ + 1)) Is Nothing Then BlokYa End If End Sub
[/vba] При открытии книги ячейки блокируются или разблокируются. И при изменении дат тоже. И все это для всех листов книги, где есть эти макросы
Но все это очень ненадежно
Да, защиту листа в макросе не прописявал
В модуле каждого листа вот такие макросы [vba]
Код
Sub BlokYa() Dim d_ As Range c1_ = Cells(4, Columns.Count).End(1).Column c0_ = 4 r0_ = 4 r1_ = Cells(Rows.Count, c0_ - 1).End(3).Row For Each d_ In Cells(r0_, c0_).Resize(1, c1_ - c0_ + 1) If IsDate(d_) Then Cells(r0_ - 1, d_.Column).Resize(r1_ - r0_ + 2, 6).Locked = DateAdd("m", 1, d_) < Date End If Next d_ End Sub
Private Sub Worksheet_Change(ByVal Target As Range) c1_ = Cells(4, Columns.Count).End(1).Column c0_ = 4 r0_ = 4 If Not Intersect(Target, Cells(r0_, c0_).Resize(1, c1_ - c0_ + 1)) Is Nothing Then BlokYa End If End Sub
[/vba] При открытии книги ячейки блокируются или разблокируются. И при изменении дат тоже. И все это для всех листов книги, где есть эти макросы
Боже, как же ненавижу я объединения ячеек. Сколько ножей в спину от них...
Но победа все же за нами.
Краткая предистория. По умолчанию - все ячейки имеют формат защищенных. Но мы этого не замечаем, пока не включена защита листа. Поэтому, если мы хотим иметь защищенными только некоторые, а остальные нет, то сначала надо снять защиту со всех, а потом пометить нужные как защищаемые.
Немножко пепла на голову. Ну извините, с картинками непривычен. Картинки сможете найти в тематических статьях.
Теперь действия. Для каждого листа создайте чистого "двойника". Его можно спрятать - он только для макросов нужен. В код самого листа (не двойника) нужно прописать махонькую программку: [vba]
Код
Private Sub Worksheet_Change(ByVal Target As Range) Sheets(ActiveSheet.Name & "_dates").Cells(Target.Row, Target.Column).Value = Now End Sub
[/vba]
Эта штука нужна для хранения даты изменения. Ее имя показывает EXCELю, что это обработчик события, которое возникает, когда какая-то ячейка изменяется. Имея ее в коде листа, после изменения ячейки EXCEL будет делать не только то, что в настройках имеется (сдвигать вниз на ячейку, например), но и то, что прописано в этой программке. Каждому листу, с которым Вы хотите таким образом работать, нужно создать двойничка и добавить код листа эту программку. Я намеренно двойничка прятать не стал и вручную изменил месяц, занесенный программой, чтобы сработала защита. В получившейся версии к имени двойничков должно быть добавлено _dates
Теперь в модуль книги нужно поместить обработчик события. Я подвязал его к открытию книги. Сами смотрите - можно будет выбрать любое из имеющегося в арсенале EXCEL. Вот этот код: [vba]
Код
Private Sub Workbook_Open() Dim sH As Object, sP As Object, cC As Range, rN As Range Dim acS As Object, acC As Range Dim mOg As Double
Application.ScreenUpdating = False
Set acS = ActiveSheet Set acC = ActiveCell mOg = Year(Now) + Month(Now) For Each sH In Worksheets If Right(sH.Name, 6) = "_dates" Then Set rN = Nothing Set sP = Sheets(Left(sH.Name, Len(sH.Name) - 6)) For Each cC In sH.UsedRange If (cC.Value <> Empty) And (mOg > (Year(cC.Value) + Month(cC.Value))) Then If sP.Cells(cC.Row, cC.Column).Locked = False Then If rN Is Nothing Then Set rN = sP.Cells(cC.Row, cC.Column).MergeArea Else Set rN = Union(rN, sP.Cells(cC.Row, cC.Column).MergeArea) End If End If End If Next cC If Not rN Is Nothing Then
sP.Unprotect Password:="321" sP.Cells.Locked = False rN.Locked = True sP.Protect DrawingObjects:=True, Contents:=True, Scenarios:=True, _ AllowFormattingCells:=True, AllowFormattingColumns:=True, _ AllowFormattingRows:=True, AllowFiltering:=True, Password:="321" End If End If Next sH acS.Select acC.Select Application.ScreenUpdating = True End Sub
[/vba]
Голову сломал, почему не давалась защита. А, оказывается, нельзя защищать отдельную ячейку, являющуюся частью объединенной - только все вместе.
Программа написана для обработки всех двойников. В ней нет "Защиты от дурака". Если двойнику не найдется соответствующий лист, скорее всего выполнение прервется по ошибке. Пароль на открытие листа везде - 321
Знал бы, сколько времени уйдет - не стал бы, наверно... Но... Что сделано, то сделано.
Боже, как же ненавижу я объединения ячеек. Сколько ножей в спину от них...
Но победа все же за нами.
Краткая предистория. По умолчанию - все ячейки имеют формат защищенных. Но мы этого не замечаем, пока не включена защита листа. Поэтому, если мы хотим иметь защищенными только некоторые, а остальные нет, то сначала надо снять защиту со всех, а потом пометить нужные как защищаемые.
Немножко пепла на голову. Ну извините, с картинками непривычен. Картинки сможете найти в тематических статьях.
Теперь действия. Для каждого листа создайте чистого "двойника". Его можно спрятать - он только для макросов нужен. В код самого листа (не двойника) нужно прописать махонькую программку: [vba]
Код
Private Sub Worksheet_Change(ByVal Target As Range) Sheets(ActiveSheet.Name & "_dates").Cells(Target.Row, Target.Column).Value = Now End Sub
[/vba]
Эта штука нужна для хранения даты изменения. Ее имя показывает EXCELю, что это обработчик события, которое возникает, когда какая-то ячейка изменяется. Имея ее в коде листа, после изменения ячейки EXCEL будет делать не только то, что в настройках имеется (сдвигать вниз на ячейку, например), но и то, что прописано в этой программке. Каждому листу, с которым Вы хотите таким образом работать, нужно создать двойничка и добавить код листа эту программку. Я намеренно двойничка прятать не стал и вручную изменил месяц, занесенный программой, чтобы сработала защита. В получившейся версии к имени двойничков должно быть добавлено _dates
Теперь в модуль книги нужно поместить обработчик события. Я подвязал его к открытию книги. Сами смотрите - можно будет выбрать любое из имеющегося в арсенале EXCEL. Вот этот код: [vba]
Код
Private Sub Workbook_Open() Dim sH As Object, sP As Object, cC As Range, rN As Range Dim acS As Object, acC As Range Dim mOg As Double
Application.ScreenUpdating = False
Set acS = ActiveSheet Set acC = ActiveCell mOg = Year(Now) + Month(Now) For Each sH In Worksheets If Right(sH.Name, 6) = "_dates" Then Set rN = Nothing Set sP = Sheets(Left(sH.Name, Len(sH.Name) - 6)) For Each cC In sH.UsedRange If (cC.Value <> Empty) And (mOg > (Year(cC.Value) + Month(cC.Value))) Then If sP.Cells(cC.Row, cC.Column).Locked = False Then If rN Is Nothing Then Set rN = sP.Cells(cC.Row, cC.Column).MergeArea Else Set rN = Union(rN, sP.Cells(cC.Row, cC.Column).MergeArea) End If End If End If Next cC If Not rN Is Nothing Then
sP.Unprotect Password:="321" sP.Cells.Locked = False rN.Locked = True sP.Protect DrawingObjects:=True, Contents:=True, Scenarios:=True, _ AllowFormattingCells:=True, AllowFormattingColumns:=True, _ AllowFormattingRows:=True, AllowFiltering:=True, Password:="321" End If End If Next sH acS.Select acC.Select Application.ScreenUpdating = True End Sub
[/vba]
Голову сломал, почему не давалась защита. А, оказывается, нельзя защищать отдельную ячейку, являющуюся частью объединенной - только все вместе.
Программа написана для обработки всех двойников. В ней нет "Защиты от дурака". Если двойнику не найдется соответствующий лист, скорее всего выполнение прервется по ошибке. Пароль на открытие листа везде - 321
Знал бы, сколько времени уйдет - не стал бы, наверно... Но... Что сделано, то сделано.Perfect2You