использование листа в пользовательской функции Excel - PullRequest
3 голосов
/ 09 января 2011

VBA, которую я пытаюсь написать, довольно проста, но я никогда не писал VBA и пришел из мира Visual Studio и C #, это действительно ад !!

Так что я действительно буду благодарен за любыепомощь / указатели / подсказки здесь

alt text

Итак, у меня есть два важных листа.Таблица диапазона имеет 2 значения на дату.Требуется результат, лист Calc принимает два значения и возвращает результат.

Я хочу поместить значения Current и OneYear для каждой даты в лист Calc и получить результатв столбец результатов.

Итак, я попытался определить UDF, но позже узнал, что не могу изменить содержимое листа в UDF.

Я попытался записать макрос, а затем надеялся перейти оттуда, ноЯ получил что-то вроде этого:

Range("A2").Select
Sheets("24Feb05-24FEB10").Select
Range("K9").Select
ActiveCell.FormulaR1C1 = "=Calc!R[-8]C[-10]"
Range("K9").Select

Я предполагаю, что R1C1 - это строка и столбец, но с какой стати это говорит -8 и -10! ??

Может кто-нибудь понять меня правильнонаправление?

Примечание: есть около 2000+ дат.

Надеюсь, мой вопрос ясен!


Обновление Я уточнюеще несколько вещей:

Im значительно упрощение таблицы Calc, на самом деле, для этого нужно 5 значений (есть столбцы до шестилетнего года) И затем этот лист вызывает около 4 других листов и делает некоторыефинансовые расчеты, которые написал какой-то не -хорошо подкованный парень.

IЯ пытался заставить финансового специалиста выразить мне в алгебре то, что он делает, поэтому я мог просто написать функцию на C #.

Я также пытался написать UDF, но, как я уже сказал, нужно поставить в значениях и получите результат, что означает, что UDF изменит лист .

Function Func1(txt As Variant) As String
//Returns the nth element from a delimited text string
    Dim txt As String
    txt = text
   Sheet4.Cells(1, 1) = txt
   Func1 = Sheet4.Cells(2, 1)//get the result value'
End Function

По сути, у меня болит голова, я изучаю / понимаю синтаксис VBA и API.

Я ищу, может быть, небольшой пример того, как я мог бы взять значения из одного листа в другой и затем вернуть некоторые другие значения?Может быть в петле !?

Ответы [ 3 ]

3 голосов
/ 09 января 2011

Вы можете сделать это более сложным, чем нужно. Как программист, я уверен, что вы цените то, что при изучении новой системы тратится немного времени с помощью Google, книг "чайников" и т. Д. Excel подчеркивает совершенно другой стиль программирования, чем, скажем, C #.

Итак, вот несколько вариантов, начиная с самого простого и самого Excel-идиоматического:

1) Используйте формулу в столбце результатов. Если расчет, который вы хотите сделать, достаточно прост, это путь. В качестве тривиального примера, скажем, ваш расчет просто сложение двух чисел. Вы бы положили формулу

=B2+C2

в ячейку E2, а затем перетащите ее вниз в столбец E. Excel будет знать, что делать и делать форумные форумы для E3 = B3 + C3 и т. Д.

Вы можете многое сделать с помощью только формул. В Excel есть много встроенных функций рабочего листа, и вы можете найти тонны материала в Интернете и в книжном магазине.

2) Запишите UDF в VBA и вызовите его из столбца результата. UDF - это функция, которая ничего не изменяет в рабочем листе. Он просто вычисляет результат на основе своих входных параметров. Вы написали бы UDF, когда у вас есть что-то слишком сложное для выполнения в формуле или если вы хотите использовать формулу в нескольких местах. (Обратите внимание, что перетаскивание раздела по диапазону является идиоматическим Excel и считается «одним местом» для СУХОХ целей).

Итак, чтобы написать UDF (давайте воспользуемся примером добавления, но вы бы написали более сложную логику), вы бы поместили такую ​​функцию в модуль кода VBA:

Public Function myUDF(current, oneYear)
    myUDF = current + oneYear
End Function

Вы бы тогда поставили формулу

=myUDF(B2, C2)

в ячейку E2 и перетащите ее вниз в столбец E.

Обратите внимание, что в этом примере я пренебрег такими вещами, как обработка ошибок. Это одна из причин, почему формулы больше «Excel», чем UDF. Теперь вам нужно начать писать код, который отличается от декларативного функционального стиля Excel, и это другая ментальная модель.

EDIT: 2.5) Использование таблицы данных Excel - Мне стыдно, что я забыл это раньше, но если у вас есть ровно одна или две ячейки, которые являются вашими независимыми параметрами, и ровно одна ячейка, которая является вашим результатом, тогда Excel имеет встроенный инструмент анализа «что, если», который вы можете использовать. Название «таблица данных» вызывает сожаление, поскольку оба эти слова сильно перегружены, но это так и называется. Вы сообщаете Excel, каковы ваши входные данные и выход, и он будет делать то, что вы хотите. См:

http://office.microsoft.com/en-us/excel-help/calculate-multiple-results-by-using-a-data-table-HP010072656.aspx

Вот небольшое вступление по этой ссылке:

Таблица данных - это диапазон ячеек, которые показывает, как меняется один или два переменные в ваших формулах (формула: A последовательность значений, ссылки на ячейки, имена, функции или операторы в клетка, которая вместе производит новый значение. Формула всегда начинается с знак равенства (=).) повлияет на Результаты этих формул. Таблицы данных предоставить ярлык для расчета несколько результатов в одной операции и способ просмотра и сравнения результатов из всех разных вариаций вместе на вашем листе.

3) Напишите макрос , который использует ваш расчетный лист как функцию. Вы можете сделать это, если у вас есть действительно сложная логика на этом листе, и ее слишком сложно преобразовать в VBA, потому что она постоянно меняется или потому, что она разрабатывается пользователем Excel, который не знает VBA и не знаком с ним. с императивным программированием. Я не собираюсь предоставлять код, но псевдокод может выглядеть так:

Public Sub doCalc()
    'for each cell in the result column
        'copy the corresponding current and oneYear cells to the calc sheet
        'Excel will recalc the calc sheet
        'copy the result cell on the calc sheet back to the Range sheet in the right place
    'end
End Sub

Теперь это довольно далеко от «пути Excel», так как вы должны сами настроить данные, а затем запустить макрос. Если вы вернетесь назад и измените некоторые из «входов», вам нужно перезапустить макрос. (Это может быть автоматизировано до некоторой степени, используя события рабочего листа.)

Многие программисты, которые являются новичками в Excel, сразу переходят к этому шагу, переводя Excel в гигантский элемент управления сеткой и игнорируя причину, по которой он существует, - автоматический пересчет.

РЕДАКТИРОВАТЬ В ОТВЕТЕ НА ДОПОЛНИТЕЛЬНУЮ ИНФОРМАЦИЮ В ВОПРОСЕ:

О.К., похоже, случай (3) уместен, потому что у вас сложный лист, который нелегко вручную перевести в код VBA или C #. Вот некоторый (упрощенный, жестко запрограммированный, не имеющий EH и т. Д.) Код, чтобы дать вам более полное представление о том, как это сделать в VBA:

Во-первых, есть макрос VBA, который притворяется, что это UDF. Обратите внимание, что это Sub, а не функция, и вы не вызываете его из формулы. Вы вызываете подпрограммы в ответ на то, что пользователь делает что-то вроде выбора пункта меню или нажатия кнопки команды:

Public Sub fakeFunct(input1, input2, outputRng As Range)
    CalcSheet.[b1] = input1
    CalcSheet.[b2] = input2

    'Excel recalcs what's in cell B3 if you have it set to automatic recalcualation

    outputRng = CalcSheet.[b3]
End Sub

В этом примере «CalcSheet» - это «кодовое имя» вашего модуля рабочего листа. (Подробнее об этом см. На отличном сайте Чипа Пирсона: http://www.cpearson.com/excel/codemods.htm)

Вы бы на самом деле вызывали вышеупомянутый макрос из другого, который проходит через ваши «входы»:

Public Sub loopFakeFunct()
    Dim i As Long
    For i = 2 To 2000
        Call fakeFunct(RangeSheet.Cells(i, 2), RangeSheet.Cells(i, 3), RangeSheet.Cells(i, 5))
    Next i
End Sub

Это то, что вы вызываете в ответ на действия пользователя, или из события Worksheet_Change и т. Д. Это будет медленно и неуклюже, и я оставляю много практических вещей VBA, но этого должно быть достаточно, чтобы получить ты начал. (Я использовал RangeSheet вместо Range в качестве кодового имени листа, чтобы избежать конфликтов с классом Range и методом Application.Range, определенным в Excel.)

4) Используйте какой-либо сторонний инструмент , который преобразует ваш рабочий лист в UDF, который затем можно вызвать, как в (2). Существуют коммерческие инструменты, которые возьмут ваш лист, позволят вам указать, какие ячейки являются входными и выходными, а затем сгенерировать код C ++ или все, что может быть скомпилировано в надстройку XLL.

5) Подождите, пока Microsoft сделает это:

http://research.microsoft.com/en-us/um/people/simonpj/papers/excel/excel.htm

6) Использование Resolver One :

http://www.resolversystems.com/products/resolver-one/

Он имеет функцию, которая позволяет использовать целую рабочую книгу как функцию в другой или, я думаю, в любом коде Python.

1 голос
/ 09 января 2011

Вы записали свой макрос в «относительном» режиме. R [-8] C [-10] означает: ячейка на 8 строк выше и на 10 столбцов слева от текущей ячейки.

0 голосов
/ 10 января 2011

В таких случаях лучше всего работать в рамках парадигмы Excel, а не преобразовывать ее в C #: не уверен, зачем вам нужен UDF, а не формулы Excel, которые кодировал ваш финансист: почему вы не можете / финансироватьпарень просто запишет некоторые формулы, чтобы подать исходные данные на листы финансового парня, а затем напишет еще несколько формул, чтобы вернуть результаты?Если вам действительно нужно сделать это с VBA, то J Tolle предоставил вам базовую архитектуру для повторяющегося цикла, но я бы рекомендовал сначала сделать это с формулами.

...