[oodisc] OOo Basic - динамические переменные: как правильно описать и использовать
Орлов Владислав
software на pro-za.com.ua
Вт Янв 25 17:37:28 MSK 2005
С Татьяниным Днем, коллеги!
Нужно расширить набор функций Calc'а несколькими специальными прибамбасами.
Поставленные задачи лучше всего (ИМХО!) решаются с помощью динамических
переменных – одно- и двунаправленные списки, деревья и прочее похожее.
Главный вопрос: Как правильно работать с динамическими объектами из Бэйсика?
Например: (пример намерено упрощенный, реальные задачи – сортировки, сложения
и вычитания диапазонов вида (1, 14-17, 5-9) – (14, 1, 8, 9) = (5-7, 15-17)
слишком громоздкие, чтобы засылать их в рассылку)
REM * Сортировка массива с исключением дублей
Option Explicit
Type elementOfTreeType
Val As Long
Left As elementOfTreeType
Right As elementOfTreeType
End Type
Sub Main
Call TestTree(Array(2, 8, 4, 3, 1, 6, 7))
Call TestTree(Array(3, 1, 2, 8, 4, 2, 8, 4, 7))
Call TestTree(Array(1, 2, 3, 3, 1, 2, 7))
Call TestTree(Array(1030, 412, 362, 217))
Call TestTree(Array(3, 1, 6, 7, 5, 2, 4, 6, 7, 3, 2, 5))
End Sub
Sub makeTree(curEl As elementOfTreeType, curVal as Long)
' Если именно такого элемента нет - вставить на свое место в дереве:
Dim newEl As New elementOfTreeType ' ?????!!!!
If curEl.Val = curVal Then Exit Sub ' Такой элемент уже был, повторно не
вносим
If curEl.Val < curVal Then ' Идем направо
If NOT IsNull(curEl.Right) Then
makeTree(curEl.Right, curVal)
Else
newEl.Val = curVal
curEl.Right = newEl
End If
Else ' curEl.Val > curVal ' Идем налево
If NOT IsNull(curEl.Left) Then
makeTree(curEl.Left, curVal)
Else
newEl.Val = curVal
curEl.Left = newEl
End If
End If
End Sub
Sub aroundTree(curEl As elementOfTreeType, sRez As String)
' Обходим дерево, заполняя строку результата
If IsNull(curEl) Then Exit Sub
aroundTree(curEl.Left, sRez) ' Пока можно влево - идем влево
' Текущий элемент вставляем в строку результата
If Len(sRez) > 0 Then sRez = sRez + ", " + CInt(curEl.Val) Else sRez =
CInt(curEl.Val)
aroundTree(curEl.Right, sRez) ' И сколько можно - идем вправо
End Sub
Sub TestTree (arrInt)
' Вывести на экран две строки - вход.массив и его же (отсортированный и без
дублей)
Dim sIn As String, sOut As String
Dim I As Integer, L As Integer, U As Integer
L = LBound(arrInt())
U = UBound(arrInt())
' Строка входящих
sIn = ""
For I = L To U
If Len(sIn) > 0 Then sIn = sIn + ", "
sIn = sIn + CInt(arrInt(I))
Next I
' Готовим дерево. Корневой элемент определяем отдельно:
Dim root As New elementOfTreeType ' Здесь его и опишем и заполним ' ?????!!!!
root.Val = arrInt(L)
' Оталкиваясь от корня - заполняем дерево
For I = L+1 To U
makeTree(root, arrInt(I))
Next I
' Обходим дерево, заполняя строку результата
sOut = ""
aroundTree(root, sOut)
' Вывод результата
MsgBox "Было >" + sIn + "<" +chr(10) + "Стало >" + sOut + "<"
End Sub
Это все работает. И результат выдает. Но рождает кучу вопросов:
1.Будет ли это работать всегда? Не сломается ли на оооочень большом массиве?
Ведь никаким явным образом мусор за собой не убирается. Или End Sub уже
достаточно, чтобы почиститься за собой?
2.Если в строках, помеченных ' ?????!!!! убрать слово New, все продолжает
работать – то есть в дерево включаются новые элементы. А откуда для них
берется память?
3.В makeTree оператор «Dim newEl» срабатывает при каждом входе в процедуру. То
есть, создается куча пустышек, из которых будет задействована только
последняя? Или не создается?
4.Должен ли я явно создавать и удалять объекты? Или Бэйсик делает это все сам?
Те примеры кода, которые уже просмотрел («Useful Macro Information For
OpenOffice By Andrew Pitonyak», The Original Documentation is
http://www.pitonyak.org/AndrewMacro.sxw ), содержат строки типа
CreateObject(...), но они все относятся к каким-то
"com.sun.star.чего-то-там"... Или это самое "чего-то-там" содержит готовое
решение всех моих задач и я опять изобретаю велосипед?
5.В окне контрольных значений можно увидеть только значение отдельной
переменной. Существует ли простой способ отслеживать значения типа newEl.Val
напрямую (без предварительного переприсвоения временной переменной)?
Всего доброго!
Владислав Орлов aka JohnSUN
Подробная информация о списке рассылки Oo-discuss