Вот ваш пример: либо скрыть строки, либо сгруппировать их и показать уровень строки 1.
Если вы дадите имя (по формулам | Менеджеру имен) каждой соответствующей области в вашем контрольном списке, вы можете обменять Range("6:10")
на Range("RowsToBeHiddenByB14")
. Если кто-то позже добавит несколько строк в именованном диапазоне в контрольный список, код все еще работает - в противном случае он должен адаптировать диапазон этого имени в диспетчере имен Excel.
Private Sub HideOrGroupSomeRows()
Dim MainSheet As Worksheet
Dim CheckSheet As Worksheet
Set MainSheet = ActiveWorkbook.Sheets("Main")
Set CheckSheet = ActiveWorkbook.Sheets("CheckList")
' Either just hide the rows:
CheckSheet.Range("6:10").EntireRow.Hidden = _
StrComp(MainSheet.Range("B14").Value, "x", vbTextCompare) = 0
CheckSheet.Range("106:116").EntireRow.Hidden = _
StrComp(MainSheet.Range("B15").Value, "x", vbTextCompare) = 0
' Or group them and show rowlevel 1:
CheckSheet.UsedRange.ClearOutline
With CheckSheet.Outline
.AutomaticStyles = False
.SummaryRow = xlAbove
.SummaryColumn = xlLeft
End With
If StrComp(MainSheet.Range("B14").Value, "x", vbTextCompare) = 0 Then _
CheckSheet.Range("6:10").EntireRow.Group
If StrComp(MainSheet.Range("B15").Value, "x", vbTextCompare) = 0 Then _
CheckSheet.Range("106:116").EntireRow.Group
CheckSheet.Outline.ShowLevels RowLevels:=1
Set MainSheet = Nothing
Set CheckSheet = Nothing
End Sub
Что при определении абстрактной Задачи и интерфейса IHasSharedData, затем в Методе, Вы проверяете, реализует ли полученная Задача IHasSharedData прежде, чем сделать блокировку. Только классы, которые реализуют интерфейсную потребность, ожидают. Я понимаю, что это старается не отвечать на фактический вопрос, но я думаю, что это было бы более чистое решение, чем использование отражения. Хотелось бы надеяться, Вы нашли бы лучшее название интерфейса, который более тесно соответствует тому, что на самом деле делают классы.
public interface IHasSharedData
{
void UpdateSharedData();
}
public abstract class Task
{
private static object LockObject = new object();
protected virtual void UpdateNonSharedData() { }
public void Method()
{
if (this is IHasSharedData)
{
lock(LockObject)
{
UpdateSharedData();
}
}
UpdateNonSharedData();
}
}
public class SharedDataTask : Task, IHasSharedData
{
public void UpdateSharedData()
{
...
}
}
Можно сделать, это сверяется с smidge отражения:
bool IsUpdateSharedDataOverridden()
{
Type t = this.GetType();
MethodInfo m = subType.GetMethod("UpdateSharedData");
return m.DeclaringType == t && m.GetBaseDefinition().DeclaringType == typeof(Task);
}
На самом деле Вы говорите приблизительно два различных объекта:
public abstract class Task {
protected virtual void UpdateNonSharedData() { }
public virtual void Method()
{
UpdateNonSharedData();
}
}
public abstract class TaskWithSharedData : Task {
private static object LockObject = new object();
protected virtual void UpdateSharedData() { }
public overrides void Method()
{
lock(LockObject)
{
UpdateSharedData();
}
base.Method();
}
}
Но, более идеальным решением будет Стратегическая модель.