Создание функции
Есть два столбца чисел (не важно каких) в Excel:
1 2
1 3
1 4
1 5
Так вот Нужно создать функцию, с помощью которой пользователь выбирает нужный диапазон в пределах двух столбцов (диапазон может быть и разорванным, т.е. выделил первую строку и 3,4 через удержание ctrl). Далее каждое число первого столбца нужно разделить на соответствующее (находящееся в той же строке) ему число второго столбца.
Итогом вычисления функции будет сумма всех частных.
Для решения этой задачи проще всего пользоваться встроенной функцией 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)
Ну я так понимаю, что вычисления в функции ты и сам напишешь, а проблема - как предоставить пользователю выбор диапазона на манер станд. функций 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
А это можно использовать с констукцией
Function name()
...
End Function
Совершенно точно.
Ты пишешь обычную функцию (токо Public) и находится она должна в модуле.
После этого ты сможешь найти свою функцию в диалоге выбора функций в разделе - пользовательские функции.
Если разместишь свой модуль в Personal.xls, то функция всегда будет под рукой, но кто специально разбрасывают модули по разным файлам (*.xls), а потом при необходимости просто запускает/открывает его. Просто если Personal.xls слишком разрастется от кол-ва модулей и кода в них, он будет много памяти занимать, а ведь он автоматом грузится со стартом Excel и соотв. висит в памяти - ну тут вообщем полнстью твой выбор, как удобнее говорится.
Совершенно точно.
Ты пишешь обычную функцию (токо Public) и находится она должна в модуле.
А мог бы ты в качестве примера накропать начало этой функции до момента Set MyRange = Application.InputBox(Prompt:="Выберите два столбца с данными.", Title:="Выберите диапазон.", Type:=8, Left:=200, Top:=-65)?
А мог бы ты в качестве примера накропать начало этой функции до момента Set MyRange = Application.InputBox(Prompt:="Выберите два столбца с данными.", Title:="Выберите диапазон.", Type:=8, Left:=200, Top:=-65)?
Вообще-то InputBox я оформил в вспомогательную функцию:
' Выводит на экран диалоговое окно выбора диапазона ячеек.
' Возвращает объект 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 файл с макросом...
Вообще-то InputBox я оформил в вспомогательную функцию:
' Выводит на экран диалоговое окно выбора диапазона ячеек.
' Возвращает объект 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 файл с макросом...
А если попробовать вот так
МАССИВЯЧЕЕК.Select
КОЛ_ВО = Selection.Areas.Count
End Function
Только если через ctrl выделяешь, пишет ЗНАЧ
Что здесь неправильно?
А если попробовать вот так
МАССИВЯЧЕЕК.Select
КОЛ_ВО = Selection.Areas.Count
End Function
Только если через ctrl выделяешь, пишет ЗНАЧ
Что здесь неправильно?
Да, совершенно правильно, если у тебя простая функция, то достаточно объявить входящую переменную и пользователь может использовать станд. Excel'ский диалог заполнения входных для функции.
Токо лучше принимать не сразу а Range, а переменную типа Variant, а потом внутри своей функции делать проверку, а то фиг его знает что пользователь подсунет.
Public Function КОЛ_ВО(МАССИВЯЧЕЕК As Variant)
If TypeName(МАССИВЯЧЕЕК)="Range" Then
End If
Да, совершенно правильно, если у тебя простая функция, то достаточно объявить входящую переменную и пользователь может использовать станд. Excel'ский диалог заполнения входных для функции.
Токо лучше принимать не сразу а Range, а переменную типа Variant, а потом внутри своей функции делать проверку, а то фиг его знает что пользователь подсунет.
Public Function КОЛ_ВО(МАССИВЯЧЕЕК As Variant)
If TypeName(МАССИВЯЧЕЕК)="Range" Then
End If
А не знаешь почему эта функция возвращает ЗНАЧ, когда я выделяю разорванный диапазон ячеек через ctrl?
А не знаешь почему эта функция возвращает ЗНАЧ, когда я выделяю разорванный диапазон ячеек через ctrl?
Так если это функция, то она должна что-то возращать, какое-то значение в эту ячейку:
Function name() As Integer
а если ты не хочешь ничего возвращать, а просто проделать некие действия, то это будет уже не функция, а макрос и запускать его уже надо как макрос (что бы Exсуд принял твою процедуру за макрос, она должна быть объявлена как Sub, а не как Function. После этого твой макрос можно будет увидеть в списке макросов.)
Так если это функция, то она должна что-то возращать, какое-то значение в эту ячейку:
Function name() As Integer
а если ты не хочешь ничего возвращать, а просто проделать некие действия, то это будет уже не функция, а макрос и запускать его уже надо как макрос (что бы Exсуд принял твою процедуру за макрос, она должна быть объявлена как Sub, а не как Function. После этого твой макрос можно будет увидеть в списке макросов.)
А разве эта функция не возвращает?
МАССИВЯЧЕЕК.Select
КОЛ_ВО = Selection.Areas.Count
End Function
По моей идее должна возвращать кол-во диапазонов в выделении
А разве эта функция не возвращает?
МАССИВЯЧЕЕК.Select
КОЛ_ВО = Selection.Areas.Count
End Function
По моей идее должна возвращать кол-во диапазонов в выделении
Ты неправильно продекларировал функцию:
нужно так:
Function КОЛ_ВО(МАССИВЯЧЕЕК As Range) As [Тип данных возращаемый функ.]
ну а потом уже как тебя
Ты неправильно продекларировал функцию:
нужно так:
Function КОЛ_ВО(МАССИВЯЧЕЕК As Range) As [Тип данных возращаемый функ.]
ну а потом уже как тебя
По-моему это необязательно По умолчаниюон присваивает variant не так ли?
Вопрос в другом Когда я отмечаю один диапазан (не разрываю), то он возвращает верный ответ (1), если отмечаю разорванный диапазон, то возвращает #ЗНАЧ! :(
По-моему это необязательно По умолчаниюон присваивает variant не так ли?
Вопрос в другом Когда я отмечаю один диапазан (не разрываю), то он возвращает верный ответ (1), если отмечаю разорванный диапазон, то возвращает #ЗНАЧ! :(
Это происходит знаешь почему...
Когда ты выделяешь через ст. диалог несколько диапазонов, то он передает в твою функцию переменные следующим образом:
NameFunc(E4:F6;E9:G10)
т.е. в итоге в твою функцию передается две переменные, потому и возникает ошибка и Excel вообще не вызывает твою функцию, из-за того что кол-во принимаемых переменных отличается.
Ситуация конечно неприятная, но ничего не поделаешь, в твоем случае придется идти на хитрость, тебе надо объявить макс. кол-во входных переменных и сделать их все (кроме первой) НЕОБЯЗАТЕЛЬНЫМИ. Т.е.:
Очень срочно нужно!
Есть два столбца чисел (не важно каких) в Excel:
1 2
1 3
1 4
1 5
Так вот Нужно создать функцию, с помощью которой пользователь выбирает нужный диапазон в пределах двух столбцов (диапазон может быть и разорванным, т.е. выделил первую строку и 3,4 через удержание ctrl). Далее каждое число первого столбца нужно разделить на соответствующее (находящееся в той же строке) ему число второго столбца.
Итогом вычисления функции будет сумма всех частных.
Вот какой код накропал для решения этой задачи
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
Можно доработать до оптимального варианта: т.е. если будут выделяться разорванные не только строки, но и столбцы, но пока некогда этим заниматься.
И еще, если есть советы, как покрасивее или правильнее это сделать, буду рад услышать.
Очень срочно нужно!
Есть два столбца чисел (не важно каких) в Excel:
1 2
1 3
1 4
1 5
Так вот Нужно создать функцию, с помощью которой пользователь выбирает нужный диапазон в пределах двух столбцов (диапазон может быть и разорванным, т.е. выделил первую строку и 3,4 через удержание ctrl). Далее каждое число первого столбца нужно разделить на соответствующее (находящееся в той же строке) ему число второго столбца.
Итогом вычисления функции будет сумма всех частных.
Не знаю, как это можно оформить в VBA.
Я бы суммировал неразрывный диапазон (т.к. очень многие функции Excel неработают с разрывными диапазонами). Просто следует обнулять ненужные произведения в сумме:
СуммаПроизвед(Ai;1/Bi;Ci), где Ci равна 1, если строка выбрана и 0 в противном случае.