В следующей статье показано, как пометить и опросить календарь с помощью мышь. 
* В реальном мире мы бы открыли форму для чтения и записи значимых записей дневника в базу данных. Это упражнение просто раскрывает механику правой кнопки мыши и находит детали на самом рабочем листе.
Прежде чем мы начнем, несколько пояснений о электронной таблице, рабочую модель которой можно найти здесь.
Процесс
Щелчок по ячейке в сетке выделит эту ячейку и изменит ее значение. Щелкните и перетащите, чтобы выделить диапазон и изменить его значения. Если ячейка заполнена, она будет очищена, в противном случае она будет заполнена, в данном случае знаком «*».
Right_click, напротив, является запросом информации из выбранной ячейки.
По сути, используются два события, а также несколько модулей.
- Рабочий лист_SelectionChange который вызывается при выборе ячейки или ячеек.
- Рабочий лист_BeforeRightClick который вызывается правой кнопкой мыши.
Проблема
Щелчок правой кнопкой мыши по ячейке также представляет собой выделение, запуская ВыборИзменить. Мы должны будем позволить этому событию идти своим чередом, очищая выбранную ячейку, прежде чем она передаст управление ПередПравоКликk, когда мы повторно заполним очищенную ячейку. Но это действие вызовет Выбор изменен событие снова, которое должно быть остановлено от его очистки еще раз.
Это мы сделаем с помощью логического флага blnLoading.
События
Введите следующее в окне кода за рабочим листом (т.е. не в модуле).
Option Explicit
Dim blnLoading As Boolean
Dim sPhase As String
Dim currCellValue As String
Dim dDate As Date
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
If ActiveCell.Row > 14 And ActiveCell.Row < 25 Then
If ActiveCell.Column > 4 And ActiveCell.Column < 47 Then 'selection is valid
On Error Resume Next
currCellValue = Target.Value 'get the target value from (ByVal Target As Range)
If blnLoading = True Then 'a value of True will force an exit from this event
blnLoading = False
Exit Sub
End If
sPhase = Cells(ActiveCell.Row, 1)
If sPhase = "" Then Exit Sub
If ActiveCell = "*" Then 'if the cell is populated, clear the selected range
Call ClearRange
Call UnblockCalendar
Else
Call PopulateRange
End If
Call RedrawCells
Range("A1").Select 'revive the SelectionChange event by changing selection.
Exit Sub
End If
End If
End Sub
Private Sub Worksheet_BeforeRightClick(ByVal Target As Range, Cancel As Boolean)
If currCellValue = "*" Then 'picked up by the previous event BEFORE it cleared it;
'This means this is a valid diary entry with detail.
blnLoading = True 'this will prevent the SelectionChange event (above) from running.
Target.Select
'currCell = Target.Address
'Range(currCell).Select
Target.Value = "*" 're-instate the value of the cell, since SelectionChange has cleared it
Call PopulateRange
dDate = Cells(13, ActiveCell.Column)
sPhase = Cells(ActiveCell.Row, 1)
MsgBox dDate & " - " & sPhase
Cancel = True 'suppress Excel’s standard right_click menus
End If
Range("A1").Select
blnLoading = False
End Sub
Это заботится о двух событиях.
Ссылочный код
Добавьте к коду следующие диапазоны заполнения и удаления:
Sub ClearRange() Selection.FormulaR1C1 = "" With Selection.Interior .Pattern = xlNone .TintAndShade = 0 .PatternTintAndShade = 0 End With End Sub Sub PopulateRange() Selection.FormulaR1C1 = "*" With Selection.Interior .Pattern = xlSolid .PatternColorIndex = xlAutomatic .ThemeColor = xlThemeColorLight2 .TintAndShade = 0.799981688894314 .PatternTintAndShade = 0 End With End Sub
Обслуживание линий электропередач
Вставьте модуль в приложение. Добавьте следующий код для поддержания внешнего вида сетки. Это было скопировано из макрорекордера, избыточность и все такое.
Option Explicit Sub UnblockCalendar() Selection.FormulaR1C1 = "" With Selection Selection.Borders(xlDiagonalDown).LineStyle = xlNone Selection.Borders(xlDiagonalUp).LineStyle = xlNone Selection.Borders(xlEdgeLeft).LineStyle = xlNone Selection.Borders(xlEdgeTop).LineStyle = xlNone Selection.Borders(xlEdgeBottom).LineStyle = xlNone Selection.Borders(xlEdgeRight).LineStyle = xlNone Selection.Borders(xlInsideVertical).LineStyle = xlNone Selection.Borders(xlInsideHorizontal).LineStyle = xlNone End With End Sub Sub RedrawCells() Selection.Borders(xlDiagonalDown).LineStyle = xlNone Selection.Borders(xlDiagonalUp).LineStyle = xlNone With Selection.Borders(xlEdgeLeft) .LineStyle = xlContinuous .ColorIndex = 0 .TintAndShade = 0 .Weight = xlThin End With With Selection.Borders(xlEdgeTop) .LineStyle = xlContinuous .ColorIndex = 0 .TintAndShade = 0 .Weight = xlThin End With With Selection.Borders(xlEdgeBottom) .LineStyle = xlContinuous .ColorIndex = 0 .TintAndShade = 0 .Weight = xlThin End With With Selection.Borders(xlEdgeRight) .LineStyle = xlContinuous .ColorIndex = 0 .TintAndShade = 0 .Weight = xlThin End With With Selection.Borders(xlInsideVertical) .LineStyle = xlContinuous .ColorIndex = 0 .TintAndShade = 0 .Weight = xlThin End With With Selection.Borders(xlInsideHorizontal) .LineStyle = xlContinuous .ColorIndex = 0 .TintAndShade = 0 .Weight = xlThin End With End Sub
Защита от катастрофы
Любой, кто много занимается разработкой Excel, знает, что сложные электронные таблицы xlsm могут время от времени давать сбой, повреждая открытый документ. В большем количестве случаев, чем можно было бы ожидать, поврежденная книга не может быть восстановлена процедурами восстановления Excel. Если резервных копий нет, то проделанная работа равна lost. Этого можно избежать с помощью инструментов, предназначенных для выполнения Исправление Excel.
Об авторе:
Феликс Хукер — эксперт по восстановлению данных в DataNumen, Inc., которая является мировым лидером в области технологий восстановления данных, включая rar ремонт и программные продукты для восстановления sql. Для получения дополнительной информации посетите www.datanumen.com
