[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