Вы можете просмотреть все открытые книги:
Public sub GetWB(byval wb_name as string) as excel.workbook
Dim wbkCurr as excel.workbook
Set getwb=nothing
For each wbkCurr in application.workbooks
If lower(left(wbkCurr.name, instr(wbkCurr.name,”.”))) = lcase(wb_name) then
Set getwb = wbkCurr
Endif
Next wbkCurr
End function
Вызвать его с помощью set wb = getwb (wb_name)
Просто проверьте, что wb все еще ничто, прежде чем продолжить [113 ]
Как насчет Шаблона "декоратор"? Это разработано для того, чтобы динамично добавить поведение к классу.
Для опций, которые поворачивают функциональность включения - выключения, я думаю, что Декоратор является способом пойти, как @Thomas Owens говорит. Я немного более обеспокоен опциями, которые изменяют функции. Декоратор многие не работают, если эти операции не могут быть объединены в цепочку. Например, если Ваш код похож:
public void ActionABC()
{
if (options.DoA)
{
A();
}
if (options.DoB)
{
B();
}
if (options.DoC)
{
C();
}
}
public void ActionCAB()
{
if (options.DoC)
{
C();
}
if (options.DoA)
{
A();
}
if (options.DoB)
{
B();
}
}
Это было бы трудно обработать с Декоратором, поскольку порядок состава отличается для для каждого Метода действия.
С 20 + опции, предполагая, что они включения - выключения, у Вас есть более чем 400 различных возможных комбинаций. Я подозреваю, что не все эти комбинации одинаково вероятны. Для вещей, которые Вы не можете обработать через Декоратора, Вы могли бы хотеть думать о режимах работы, которые отображаются на комбинациях настроек. Поддерживайте только те режимы, которые больше всего ожидаются. Если количество режимов является небольшим, Вы могли бы обработать это с разделением на подклассы, затем использовать Декораторов для добавления функциональности к подклассу, представляющему режим, который выбрал пользователь. Вы могли использовать Фабрику, чтобы выбрать и создать надлежащий класс на основе конфигурации.
В сущности я предполагаю, что говорю, что можно хотеть рассмотреть, нужны ли Вам столько гибкости и сопутствующей сложности, сколько Вы создаете. Рассмотрите сокращение количества параметров конфигурации путем сворачивания их в меньшее число более вероятно, чтобы быть используемыми режимами.
Существует действительно другой шаблон, названный шаблоном разработчика точно с этой целью. Обычно, полезный, когда у Вас есть класс, но каждая опция 'конфигурации' могла быть сделана дополнительной, возможно, в некоторых комбинациях только. (http://en.wikipedia.org/wiki/Builder_pattern, но это точно не описывает мой сценарий tho).
Вы создаете два класса - класс, который Вы хотите создать, и разработчик. Класс разработчика является классом, который заботится о разработке, какие комбинации опций являются дополнительными, какая комбинация имеет смысл и т.д. и т.д.
например, Вы хотите представить салат - но только определенные компоненты 'имеют приятный вкус', поэтому только они должны быть сделаны.
Class Salad {
private Veggie v;
private Egg e;
private Meat m;
// etc etc, lots of properties
//constructor like this is nice
Salad(SaladBuilder builder) {
//query the builder to actually build the salad object.
//getVeggie() will either return the supplied value,
//or a default if none exists.
this.v = builder.getVeggie();
//rest of code omitted
}
//otherwise this constructor is fine, but needs a builder.build() method
Salad(Veggie v, Meat m, Egg e) { //code omitted
}
}
class SaladBuilder {
//some default, or left to null depending on what is needed
private Veggie v = SOME_DEFAULT_VEGGIE;
private Egg e;
private Meat m;
// etc etc, lots of properties.
//similar functions for each ingredient,
//or combination of ingredients that only make sense together
public SaladBuilder addIngredient(Meat m) {
this.m = m;
return this;
}
public SaladBuilder addIngredient(Veggie v) {
this.v = v;
return this;
}
public Salad build(){
// essentially, creates the salad object, but make sure optionals
// are taken care of here.
return new Salad(getBeggie(), getMeat(), getEgg());
}
}
пример использования
Salad s = new SaladBuilder().addIngredient(v).addIngredient(m).build();
Я думаю о Шаблоне "команда".
Это посмотрело бы что-то как:
public class MyClass {
interface Command {
void execute(int a);
}
static class DoThisSimpleCommand implements Command {
void execute(int a) {
// do this simple
}
}
static class DoThisAnotherWayCommand implements Command {
void execute(int a) {
// do this another way
}
}
private Command doThisCommand;
MyClass() {
initDoThisCommand();
}
private void initDoThisCommand() {
if (config.getDoThisMethod().equals("simple")) {
doThisCommand = new DoThisSimpleCommand();
} else {
doThisCommand = new DoThisAnotherWayCommand();
}
}
void doThis(int a) {
doThisCommand.execute(a);
}
}
Другими словами; Вы делегируете ответственность перед реализацией, которой Вы инстанцируете на конструкции. Теперь Ваш doThis просто делегирует, и фактическая функциональность чисто убрана в своем собственном классе.
Что относительно чего-то вроде этого?
IdMap elementsById = (options.useIdAttribute) ? new IdMapImpl() : new NullIdMap();
public Element getElementById(final string id) {
return elementsById.get(id);
}
На основе следующих типов:
interface IdMap {
Element get(String id);
}
class NullIdMap implements IdMap {
public Element get(final String id) {
throw new Exception(/* Error message */);
}
}
class IdMapImpl implements IdMap {
Map<String, Element> elements = new HashMap<String, Element>();
public Element get(final String id) {
rejectEmpty(id);
return elements.get(id.toLowerCase());
}
}
Здесь мы используем шаблон NullObject для обработки особого случая, где useIdAttribute отключен. Конечно, существует компромисс - сам класс синтаксического анализатора более выразителен, в то время как существует теперь 4 типа, а не 1. Этот рефакторинг может походить на излишество для просто получить метода, но когда Вы добавляете 'помещенный ()', метод и т.д. это обладает преимуществом локализации логики 'особого случая' в едином классе (NullIdMap).
[rejectEmpty является вспомогательным методом, который выдает исключение, если передано пустая строка.]
Как Вы намереваетесь осуществить правила для опций, которые являются взаимозависимыми? Если можно добавить опции динамично, Вы можете быть вынуждены иметь несколько invokers, если Вы шаблон "команда", или Вам, вероятно, придется реализовать оператор выбора для того, чтобы пристроить то, что управляет, чтобы Вы должны были выполниться.
Используя что-то как стратегия или политика шаблон мог бы быть полезным здесь. Это - хороший способ инкапсулировать или выгрузить различные реализации алгоритма на основе вещей как конфигурация или (не) существование некоторых конкретных данных во времени выполнения.
В Вашем сценарии, если Ваш класс парсинга обычно имеет те же типы поведения (что-то в, что-то) кроме изменения внутренних алгоритмов, это - что-то, на чем Вы могли бы хотеть основывать реализацию.