calc4fem
|
когда то читал про эту возможность, но сейчас найти не могу. Подскажите пожалуйста ссылку на вики или пример.
|
|
|
Записан
|
|
|
|
Yakov
|
Это было на codesnippets, но их удалили вот восстановленная копия из веб-архива восстановленная копия из веб-архива OO-Snippets: Call built-in functions Commons Keywords built-in function, function, min Language OOBasic Application Calc Authors Kohei Yoshida (initial) Paolo Mantovani Supported Versions 1.0.x 1.1.x 2.0.x Supported OS All Question Answer To use Calc's built-in functions in Basic macro, you need to first create a service object of com.sun.star.sheet.FunctionAccess, and call the method "callFunction". Arguments are passed to this method as an array object even if there is only one argument. If the argument is a cell range, a cell range object must first be created, and passed into an array object before it is injected into the callFunction method (see the example code). Code-Snippet-Listing (snippet-source) Sub callFunction
svc = createUnoService( "com.sun.star.sheet.FunctionAccess" )
' Calculate min of numbers. arg = array( 10, 23, 5, 345 ) print svc.callFunction( "MIN", arg )
' Calculate min of values in cell range A1:A17 oSheet = ThisComponent.Sheets(0) ' Get leftmost sheet oCellRange = oSheet.getCellRangeByPosition( 0, 0, 0, 16 ) 'A1:A17 arg = array( oCellRange ) print svc.callFunction( "MIN", arg )
End Sub
|
|
|
Записан
|
|
|
|
rami
|
Читайте Питоньяка. http://admin-smolensk.ru/~websprav/freesoft/freesoft/OpenOffice.org%20Macros%20Explained.Master.pdfВот один из примеров: заполните числами диапазон A1:D10 Sub asd dim cus, a$, b$, c$, z() Sheet = ThisComponent.CurrentController.ActiveSheet cus=createUnoService("com.sun.star.sheet.FunctionAccess") 'доступ к функциям a="Максимум" b="Среднее" c="Ячеек" z=Sheet.getCellRangeByPosition(0, 0, 4, 9) print a;cus.callFunction("max",array(z)),b;cus.callFunction("average",array(z)),c;cus.callFunction("count",array(z)) End Sub А вот снимок стр. 391 из книги "Эндрю Питоньяк. OpenOffice.org Объяснение Макросов."
|
|
|
Записан
|
|
|
|
calc4fem
|
Да - спасибо. В принципе все ясно. Проблема общая для Бэйсик - то что матрицы которые приходят из UNO или как там его и матрицы которые его родные - они как бы немного разные. То есть первые при проверке переменных выводятся как то так aux(1,2) вторые aux(1)(2) что то типа того. после некоторых экспериментов получилось вот что 1) svc.callFunction - получается 2) вывести массив полученный таким образом на лист не получается - только после "приведения к стандартному виду" через цикл 3) какой то фэйл с "MMULT" (возможно размерности матриц не правильно ввел Если удасться то что задумывал - отпишусь еще Function Linsolu(K,P) 'Spreadsheet Array Function for Solving linear system {K}{u}={P} 'returns vector {u} ' svc = createUnoService( "com.sun.star.sheet.FunctionAccess" ) 'даю знать шо это массивы arg=array(K) arg1=array(P) 'пытаюсь обратить функцию arg2= svc.callFunction("MINVERSE",arg()) 'получилось
'Пытаюсь умножить одну матрицу на другую 'Linsolu=svc.callFunction("MMULT", array(arg2,arg1) ) 'Не получается, может что то не так.
'Пытаюсь вывести обращенную матрицу как результат 'Linsolu=arg2 ' фейл
'Преобразую обращенную матрицу в несколько иной вид - новая матрица arg3 Dim arg3(1 To dimension_of_array, 1 To dimension_of_array)
dimension_of_array=UBound(arg2,1)+1 For i=1 To dimension_of_array auxvararray=arg2(i-1) For j=1 To dimension_of_array arg3(i,j)=auxvararray(j-1) Next j Next i
Linsolu=arg3 ' вот так получается вернуть хоть что то.
End Function
|
|
|
Записан
|
|
|
|
Hasim
Форумчанин
 
Offline
Сообщений: 754
Woe from wit
|
calc4fem Вместо только одной функции целиком ваш файл не покажете? Чтобы не ломать голову, какие такие матрицы вы перемножаете.
|
|
|
Записан
|
|
|
|
|
calc4fem
|
Спасибо - нашел ошибку сам даже у себя. Все таки отладчик в StarBasic не очень доходчивый, просто не понял где и что. Интересный вопрос который я пока не выяснил. Есть ли у сложных математических вычислений фора по производительности если делать их через функции Calc или же программировать непосредственно в Basic (через цикл - поэлементно) По идее первое должно быть производительней, ведь Calc наверняка оперирует целыми массивами в одной из своих нативных библиотек, а код Бэйсика - вроде бы интерпретируемый. Но это надо брать большие матрицы чтобы выяснить что на самом деле Function mmult1(K,P)
'Тест для произведения матриц svc = createUnoService( "com.sun.star.sheet.FunctionAccess" )
' arg2=svc.callFunction("MMULT", Array(K,P) )
dimension_of_array=UBound(arg2,1)+1
'Преобразую матрицу в несколько иной вид - новая матрица arg3 Dim arg3(1 To dimension_of_array, 1 To dimension_of_array)
dimension_of_array=UBound(arg2,1)+1 For i=1 To dimension_of_array auxvararray=arg2(i-1) For j=1 To dimension_of_array arg3(i,j)=auxvararray(j-1) Next j Next i
mmult1=arg3
End Function Тут выкладываю файлы с тестом для произведения матриц и с тем что я сначала хотел- функцией для решения линейных уравнений
|
|
« Последнее редактирование: 7 Июль 2014, 22:16 от calc4fem »
|
Записан
|
|
|
|
Hasim
Форумчанин
 
Offline
Сообщений: 754
Woe from wit
|
Интересный вопрос который я пока не выяснил. Есть ли у сложных математических вычислений фора по производительности если делать их через функции Calc или же программировать непосредственно в Basic (через цикл - поэлементно) По идее первое должно быть производительней, ведь Calc наверняка оперирует целыми массивами в одной из своих нативных библиотек, а код Бэйсика - вроде бы интерпретируемый. Тут "к бабке не ходи" - код Бэйсика на 2-3 порядка медленнее функций Калка - проверено многократно.
|
|
|
Записан
|
|
|
|
calc4fem
|
Спасибо, проверю конечно обязательно (чтобы подтвердить эту мысль насчет скорости) В принципе медленность не играет роли в большинстве практических приложений, но решение СЛАУ - как раз тот случай где может и играть. Насчет разного вида массивов - с чем это связано, что после всякого UnoService приходится преобразовывать массивы в традиционный вид? Вероятно что ни с чем, просто так, от java все пошло?
|
|
|
Записан
|
|
|
|
dndn
|
Доброго времени суток! "Стою на асфальте я, в лыжи обутый..."  Необходимо найти значение элемента в массиве. В Calc для этого есть соответствующая функция "MATCH". Аргументы: искомое значение; массив; тип. В то же время для вызова функции Calc в макросе Бэйсика аргументы: наименование функции; массив аргументов. Как задать массив в массиве аргументов? Ну например, для функции "MAX" все просто: FuncService = CreateUnoService("com.sun.star.sheet.FunctionAccess") FuncResult = FuncService.callFunction("MAX", array(1,3,8,19,2)) А для "MATCH": FuncResult = FuncService.callFunction("MATCH", array (3, array (1, 2, 3, 4, 5), 0)) выдает ошибку "com.sun.star.lang.IllegalArgumentException" Понятно, что неправильно передается массив в массиве. Так что надо, что лыжи поехали?
|
|
« Последнее редактирование: 18 Декабрь 2014, 14:01 от dndn »
|
Записан
|
|
|
|
Hasim
Форумчанин
 
Offline
Сообщений: 754
Woe from wit
|
Работает, если передается не массив, а ссылка на строку или столбец, как и написано в справке: MATCH(Условие поиска; Массив; Тип) Условие_поиска: значение для поиска в массиве с одной строкой или столбцом. Массив: ссылка для поиска. Это может быть одна строка или столбец, либо часть одной строки или столбца. Тип: параметр, который может принимать значения 1, 0 или -1.
sub Main
FuncService = CreateUnoService("com.sun.star.sheet.FunctionAccess") oRange = ThisComponent.Sheets(0).getCellRangeByName("A1:A17")
FuncResult = FuncService.callFunction("MATCH", Array(71, oRange, 0) )
MsgBox FuncResult
End sub Можно ли массив превратить в ссылку - вопрос?
|
|
« Последнее редактирование: 24 Декабрь 2014, 00:14 от Hasim »
|
Записан
|
|
|
|
rami
|
Номер i элемента x в массиве a() я бы искал перебором так: Sub Main Dim i, a(), x 'вычисляет номер элемента массива x=222 a=array(5,3,8,19,2,22) For i=0 To UBound(a) If a(i)=x Then Exit For If i=UBound(a) Then Print x & " не найдено" : Exit Sub Next Print x & " находится на " & i & " месте" End Sub
|
|
|
Записан
|
|
|
|
Hasim
Форумчанин
 
Offline
Сообщений: 754
Woe from wit
|
Если все-таки хочется использовать функцию MATCH, а не заниматься перебором, как rami, то надо вспомнить старый добрый VBA от Microsoft: Option VBASupport 1
Sub zaq() Dim arr(6)
arr(0) = 10 arr(1) = 11 arr(2) = 12 arr(3) = 13 arr(4) = 14 arr(5) = 15 am = Application.Match(13, arr, 0) MsgBox am-1
End Sub
|
|
|
Записан
|
|
|
|
|