Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Создание функции

464
05 апреля 2004 года
WildAn
147 / / 19.05.2003
Очень срочно нужно!
Есть два столбца чисел (не важно каких) в Excel:
1 2
1 3
1 4
1 5
Так вот Нужно создать функцию, с помощью которой пользователь выбирает нужный диапазон в пределах двух столбцов (диапазон может быть и разорванным, т.е. выделил первую строку и 3,4 через удержание ctrl). Далее каждое число первого столбца нужно разделить на соответствующее (находящееся в той же строке) ему число второго столбца.
Итогом вычисления функции будет сумма всех частных.
258
05 апреля 2004 года
SergeySV
1.5K / / 19.03.2003
Ну я так понимаю, что вычисления в функции ты и сам напишешь, а проблема - как предоставить пользователю выбор диапазона на манер станд. функций Excel'я.

Для решения этой задачи проще всего пользоваться встроенной функцией Excel'я:
Set MyRange = Application.InputBox(Prompt:="Выберите два столбца с данными.", Title:="Выберите диапазон.", Type:=8, Left:=200, Top:=-65)

Type:=8 отвечает за окно диалога выбора диапазона ячеек, при этом выполнение кода приостанавливается, появляется ст. окошко и пользователь может либо выбрать диапазон мышкой (перемещаясь по листам и зажимая контрол для выбора несвязных ячеек) или ввыести адрес вручную, после нажатия OK, функция возратит тебе выделенный range объект. Надо токо предусмотреть ситуацию когда пользователь откажется и ничего не выберет, тогда твой range будет Nothing (проверить это можно следующим кодом: If TypeName(MyRange)="Nothing" Then .... Else ... End If)
464
05 апреля 2004 года
WildAn
147 / / 19.05.2003
Цитата:
Originally posted by SergeySV
Ну я так понимаю, что вычисления в функции ты и сам напишешь, а проблема - как предоставить пользователю выбор диапазона на манер станд. функций Excel'я.

Для решения этой задачи проще всего пользоваться встроенной функцией Excel'я:
Set MyRange = Application.InputBox(Prompt:="Выберите два столбца с данными.", Title:="Выберите диапазон.", Type:=8, Left:=200, Top:=-65)

Type:=8 отвечает за окно диалога выбора диапазона ячеек, при этом выполнение кода приостанавливается, появляется ст. окошко и пользователь может либо выбрать диапазон мышкой (перемещаясь по листам и зажимая контрол для выбора несвязных ячеек) или ввыести адрес вручную, после нажатия OK, функция возратит тебе выделенный range объект. Надо токо предусмотреть ситуацию когда пользователь откажется и ничего не выберет, тогда твой range будет Nothing (проверить это можно следующим кодом: If TypeName(MyRange)="Nothing" Then .... Else ... End If)


А это можно использовать с констукцией
Function name()
...
End Function

258
05 апреля 2004 года
SergeySV
1.5K / / 19.03.2003
Цитата:
Originally posted by WildAn

А это можно использовать с констукцией
Function name()
...
End Function



Совершенно точно.
Ты пишешь обычную функцию (токо Public) и находится она должна в модуле.

После этого ты сможешь найти свою функцию в диалоге выбора функций в разделе - пользовательские функции.
Если разместишь свой модуль в Personal.xls, то функция всегда будет под рукой, но кто специально разбрасывают модули по разным файлам (*.xls), а потом при необходимости просто запускает/открывает его. Просто если Personal.xls слишком разрастется от кол-ва модулей и кода в них, он будет много памяти занимать, а ведь он автоматом грузится со стартом Excel и соотв. висит в памяти - ну тут вообщем полнстью твой выбор, как удобнее говорится.

464
05 апреля 2004 года
WildAn
147 / / 19.05.2003
Цитата:
Originally posted by SergeySV


Совершенно точно.
Ты пишешь обычную функцию (токо Public) и находится она должна в модуле.


А мог бы ты в качестве примера накропать начало этой функции до момента Set MyRange = Application.InputBox(Prompt:="Выберите два столбца с данными.", Title:="Выберите диапазон.", Type:=8, Left:=200, Top:=-65)?

258
05 апреля 2004 года
SergeySV
1.5K / / 19.03.2003
Цитата:
Originally posted by WildAn

А мог бы ты в качестве примера накропать начало этой функции до момента Set MyRange = Application.InputBox(Prompt:="Выберите два столбца с данными.", Title:="Выберите диапазон.", Type:=8, Left:=200, Top:=-65)?



Вообще-то InputBox я оформил в вспомогательную функцию:

Код:
Public Function MyRangeBox(Prompt As String, Title As String) As Range
 ' Выводит на экран диалоговое окно выбора диапазона ячеек.
 ' Возвращает объект Range, если диапазон не выбран, то - Nothing.
 '[Prompt] - Текст внутри диалогового окна.
 '[Title]  - Текст в заголовке окна.
 
 On Error GoTo Er_
 
  Set MyRangeBox = Application.InputBox(Prompt:=Prompt, Title:=Title, Type:=8, Left:=200, Top:=-65)
   
Ex_:
 Exit Function
   
Er_:
  Set MyRangeBox = Nothing
  Resume Ex_
 
End Function


А основную функцию (вернее даже не функцию, а макрос) где я использую MyRangeBox я конечно могу показать, но она достаточно большая и к тому же использует вспомогательную UserForm, так что для ее работы нужна еще форма (даже не одна).
Ну если тебе очень надо, то я могу конечно выложить здесь xls файл с макросом...
464
05 апреля 2004 года
WildAn
147 / / 19.05.2003
Цитата:
Originally posted by SergeySV


Вообще-то InputBox я оформил в вспомогательную функцию:
Код:
Public Function MyRangeBox(Prompt As String, Title As String) As Range
 ' Выводит на экран диалоговое окно выбора диапазона ячеек.
 ' Возвращает объект Range, если диапазон не выбран, то - Nothing.
 '[Prompt] - Текст внутри диалогового окна.
 '[Title]  - Текст в заголовке окна.
 
 On Error GoTo Er_
 
  Set MyRangeBox = Application.InputBox(Prompt:=Prompt, Title:=Title, Type:=8, Left:=200, Top:=-65)
   
Ex_:
 Exit Function
   
Er_:
  Set MyRangeBox = Nothing
  Resume Ex_
 
End Function


А основную функцию (вернее даже не функцию, а макрос) где я использую MyRangeBox я конечно могу показать, но она достаточно большая и к тому же использует вспомогательную UserForm, так что для ее работы нужна еще форма (даже не одна).
Ну если тебе очень надо, то я могу конечно выложить здесь xls файл с макросом...


А если попробовать вот так

 
Код:
Function КОЛ_ВО(МАССИВЯЧЕЕК As Range)

МАССИВЯЧЕЕК.Select
КОЛ_ВО = Selection.Areas.Count

End Function

Только если через ctrl выделяешь, пишет ЗНАЧ
Что здесь неправильно?
258
05 апреля 2004 года
SergeySV
1.5K / / 19.03.2003
Цитата:
Originally posted by WildAn

А если попробовать вот так
 
Код:
Function КОЛ_ВО(МАССИВЯЧЕЕК As Range)

МАССИВЯЧЕЕК.Select
КОЛ_ВО = Selection.Areas.Count

End Function

Только если через ctrl выделяешь, пишет ЗНАЧ
Что здесь неправильно?



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

Токо лучше принимать не сразу а Range, а переменную типа Variant, а потом внутри своей функции делать проверку, а то фиг его знает что пользователь подсунет.

Public Function КОЛ_ВО(МАССИВЯЧЕЕК As Variant)

If TypeName(МАССИВЯЧЕЕК)="Range" Then

End If

464
05 апреля 2004 года
WildAn
147 / / 19.05.2003
Цитата:
Originally posted by SergeySV


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

Токо лучше принимать не сразу а Range, а переменную типа Variant, а потом внутри своей функции делать проверку, а то фиг его знает что пользователь подсунет.

Public Function КОЛ_ВО(МАССИВЯЧЕЕК As Variant)

If TypeName(МАССИВЯЧЕЕК)="Range" Then

End If


А не знаешь почему эта функция возвращает ЗНАЧ, когда я выделяю разорванный диапазон ячеек через ctrl?

258
05 апреля 2004 года
SergeySV
1.5K / / 19.03.2003
Цитата:
Originally posted by WildAn

А не знаешь почему эта функция возвращает ЗНАЧ, когда я выделяю разорванный диапазон ячеек через ctrl?



Так если это функция, то она должна что-то возращать, какое-то значение в эту ячейку:

Function name() As Integer

а если ты не хочешь ничего возвращать, а просто проделать некие действия, то это будет уже не функция, а макрос и запускать его уже надо как макрос (что бы Exсуд принял твою процедуру за макрос, она должна быть объявлена как Sub, а не как Function. После этого твой макрос можно будет увидеть в списке макросов.)

464
05 апреля 2004 года
WildAn
147 / / 19.05.2003
Цитата:
Originally posted by SergeySV


Так если это функция, то она должна что-то возращать, какое-то значение в эту ячейку:

Function name() As Integer

а если ты не хочешь ничего возвращать, а просто проделать некие действия, то это будет уже не функция, а макрос и запускать его уже надо как макрос (что бы Exсуд принял твою процедуру за макрос, она должна быть объявлена как Sub, а не как Function. После этого твой макрос можно будет увидеть в списке макросов.)


А разве эта функция не возвращает?

 
Код:
Function КОЛ_ВО(МАССИВЯЧЕЕК As Range)

МАССИВЯЧЕЕК.Select
КОЛ_ВО = Selection.Areas.Count

End Function
По моей идее должна возвращать кол-во диапазонов в выделении
258
05 апреля 2004 года
SergeySV
1.5K / / 19.03.2003
Цитата:
Originally posted by WildAn

А разве эта функция не возвращает?
 
Код:
Function КОЛ_ВО(МАССИВЯЧЕЕК As Range)

МАССИВЯЧЕЕК.Select
КОЛ_ВО = Selection.Areas.Count

End Function
По моей идее должна возвращать кол-во диапазонов в выделении



Ты неправильно продекларировал функцию:
нужно так:

Function КОЛ_ВО(МАССИВЯЧЕЕК As Range) As [Тип данных возращаемый функ.]

ну а потом уже как тебя

464
05 апреля 2004 года
WildAn
147 / / 19.05.2003
Цитата:
Originally posted by SergeySV


Ты неправильно продекларировал функцию:
нужно так:

Function КОЛ_ВО(МАССИВЯЧЕЕК As Range) As [Тип данных возращаемый функ.]

ну а потом уже как тебя


По-моему это необязательно По умолчаниюон присваивает variant не так ли?
Вопрос в другом Когда я отмечаю один диапазан (не разрываю), то он возвращает верный ответ (1), если отмечаю разорванный диапазон, то возвращает #ЗНАЧ! :(

258
05 апреля 2004 года
SergeySV
1.5K / / 19.03.2003
Цитата:
Originally posted by WildAn

По-моему это необязательно По умолчаниюон присваивает variant не так ли?
Вопрос в другом Когда я отмечаю один диапазан (не разрываю), то он возвращает верный ответ (1), если отмечаю разорванный диапазон, то возвращает #ЗНАЧ! :(



Это происходит знаешь почему...
Когда ты выделяешь через ст. диалог несколько диапазонов, то он передает в твою функцию переменные следующим образом:
NameFunc(E4:F6;E9:G10)
т.е. в итоге в твою функцию передается две переменные, потому и возникает ошибка и Excel вообще не вызывает твою функцию, из-за того что кол-во принимаемых переменных отличается.

Ситуация конечно неприятная, но ничего не поделаешь, в твоем случае придется идти на хитрость, тебе надо объявить макс. кол-во входных переменных и сделать их все (кроме первой) НЕОБЯЗАТЕЛЬНЫМИ. Т.е.:

 
Код:
Public Function CountArea(rRange1 As Variant, Optional rRange2 As Variant, Optional rRange3 As Variant, и т.д.) As Long
464
06 апреля 2004 года
WildAn
147 / / 19.05.2003
Цитата:
Originally posted by WildAn
Очень срочно нужно!
Есть два столбца чисел (не важно каких) в Excel:
1 2
1 3
1 4
1 5
Так вот Нужно создать функцию, с помощью которой пользователь выбирает нужный диапазон в пределах двух столбцов (диапазон может быть и разорванным, т.е. выделил первую строку и 3,4 через удержание ctrl). Далее каждое число первого столбца нужно разделить на соответствующее (находящееся в той же строке) ему число второго столбца.
Итогом вычисления функции будет сумма всех частных.


Вот какой код накропал для решения этой задачи

Код:
Public Function КОЛ_ВО(ParamArray МАССИВЯЧЕЕК())
Dim areascount, rowscount As Integer
d = 0
Sum = 0
For areascount = 0 To UBound(МАССИВЯЧЕЕК)
    For rowscount = 1 To МАССИВЯЧЕЕК(areascount).Rows.Count
    If МАССИВЯЧЕЕК(i)(rowscount, 2) = 0 Then GoTo l1
    d = d + МАССИВЯЧЕЕК(areascount)(rowscount, 1) / МАССИВЯЧЕЕК(areascount)(rowscount, 2)
l1:
    Next rowscount
    Sum = Sum + d
    d = 0
Next areascount
КОЛ_ВО = Sum
End Function

Можно доработать до оптимального варианта: т.е. если будут выделяться разорванные не только строки, но и столбцы, но пока некогда этим заниматься.
И еще, если есть советы, как покрасивее или правильнее это сделать, буду рад услышать.
1.3K
06 апреля 2004 года
IKor
116 / / 04.12.2002
Цитата:
Originally posted by WildAn
Очень срочно нужно!
Есть два столбца чисел (не важно каких) в Excel:
1 2
1 3
1 4
1 5
Так вот Нужно создать функцию, с помощью которой пользователь выбирает нужный диапазон в пределах двух столбцов (диапазон может быть и разорванным, т.е. выделил первую строку и 3,4 через удержание ctrl). Далее каждое число первого столбца нужно разделить на соответствующее (находящееся в той же строке) ему число второго столбца.
Итогом вычисления функции будет сумма всех частных.



Не знаю, как это можно оформить в VBA.
Я бы суммировал неразрывный диапазон (т.к. очень многие функции Excel неработают с разрывными диапазонами). Просто следует обнулять ненужные произведения в сумме:
СуммаПроизвед(Ai;1/Bi;Ci), где Ci равна 1, если строка выбрана и 0 в противном случае.

Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог