Поиск в List

  • Автор темы Darker
  • Дата начала
Статус
Закрыто для дальнейших ответов.
D

Darker

#1
Есть свойство для подсчета элементов списка по критерию
Код:
Property Get DocInfoCollCount(ExType As Integer, ByForm As String, ExKind As String, StopAtFirst As Boolean) As Long '---- ExType - вид исполнителя, ByForm - форма
Dim c As Long
c=0

If ExType>CONST_ALLEXTYPE Then
If Not CheckExistingListTag("ExType") Then Print Getthreadinfo(1)&". Не сработал подсчет по типу исполнителя. Из-за отсутствия ExType":Goto ex
End If

If ByForm<>CONST_ALLFORM Then
If Not CheckExistingListTag("form") Then Print Getthreadinfo(1)&". Не сработал подсчет по форме исполнителя. Из-за отсутствия form":Goto ex
End If

If ExKind>CONST_ALLEXKIND Then
If Not CheckExistingListTag("ExIsCorr") Then Print Getthreadinfo(1)&". Не сработал подсчет по виду исполнителя. Из-за отсутствия ExIsCorr":Goto ex
End If

If ExKind=CONST_KINDEXECUTOR Or ExKind=CONST_KINDCORRESPONDENT Then
If ExType=CONST_INNER Or ExType=CONST_OUTER Then'-------------------------- Внутренние
If ExType=CONST_INNER Then tempType="InnerExecutors" Else tempType="OuterExecutors"
If ByForm=CONST_ALLFORM Then	'---- Все формы
Forall DI In DocInfoColl
If DI.Field("ExIsCorr")=ExKind And DI.Field("ExType")=tempType Then c=c+1: If StopAtFirst Then Goto ex
End Forall
Else'----------------------------------------------- По заданной форме
Forall DI In DocInfoColl
If DI.Field("ExIsCorr")=ExKind And DI.Field("ExType")=tempType And DI.Field("form")=ByForm Then c=c+1: If StopAtFirst Then Goto ex
End Forall
End If
Else
If ByForm=CONST_ALLFORM Then'---- Все формы
Forall DI In DocInfoColl
If I.Field("ExIsCorr")=ExKind Then c=c+1: If StopAtFirst Then Goto ex
End Forall
Else'----------------------------------------------- По заданной форме
Forall DI In DocInfoColl
If DI.Field("ExIsCorr")=ExKind And DI.Field("form")=ByForm Then c=c+1: If StopAtFirst Then Goto ex
End Forall
End If
End If
Else
If ExType=CONST_INNER Or ExType=CONST_OUTER Then'-------------------------- Внутренние
If ExType=CONST_INNER Then tempType="InnerExecutors" Else tempType="OuterExecutors"
If ByForm=CONST_ALLFORM Then	'---- Все формы
Forall DI In DocInfoColl
If DI.Field("ExType")=tempType Then c=c+1: If StopAtFirst Then Goto ex
End Forall
Else'----------------------------------------------- По заданной форме
Forall DI In DocInfoColl
If DI.Field("ExType")=tempType And DI.Field("form")=ByForm Then c=c+1: If StopAtFirst Then Goto ex
End Forall
End If
Else
If ByForm=CONST_ALLFORM Then'---- Все формы
Forall DI In DocInfoColl
c=c+1
If StopAtFirst Then Goto ex
End Forall
Else'----------------------------------------------- По заданной форме
Forall DI In DocInfoColl
If DI.Field("form")=ByForm Then c=c+1: If StopAtFirst Then Goto ex
End Forall
End If
End If
End If
ex:	DocInfoCollCount=c
End Property
Хотел не копипастить циклы, а закинуть в процедурку, так условие не знаю как передать в качестве "параметра"
Нуждаюсь в рефакторинге
 

lmike

нет, пердело совершенство
Lotus team
27.08.2008
6 599
277
#2
зависит от задачи, можно колекцию получать через DbSearch
можно формировать List по ключам, элементом будет массив с рефами доков...
 

Mady

Well-known member
16.09.2006
65
0
#3
можно формировать List по ключам, элементом будет массив с рефами доков...


Если в List записать доки ваше приложение скорее всего умрет, от не хватки памяти. плохой вариант хранить нотес документы в листе.
 
Y

Yakov

#4
Darker, я бы разделил функцию на две: проверка того, что хоть один элемент соответствует критерию, и собственно подсчет количества элементов. Тогда не нужен будет последний параметр.
И вот что у меня получилось (писал в блокноте, не компилировал, не проверял):
<div class="sp-wrap"><div class="sp-head-wrap"><div class="sp-head folded clickable">"Код"</div></div><div class="sp-body"><div class="sp-content">
Код:
'Предполагаю, что где-то объявлен класс DocInfo, экземпляры которого находядся
'в списке DocInfoColl List As DocInfo, в котором и происходит поиск элементов. 

'Вспомогательные классы для проверки условий

Private Class Condition
Public Function match(di As DocInfo) As Boolean
match = False
End Function
End Class

Private Class AndCondition As Condition
Private cond1 As Condition
Private cond2 As Condition
Public Sub new(cond1 As Condition, cond2 As Condition)
Set Me.cond1 = cond1
Set Me.cond2 = cond2
End Sub
Public Function match(di As DocInfo) As Boolean
match = cond1.match(di) And cond2.match(di)
End Function
End Class

Private Class OrCondition As Condition 'Здесь не используется, но на всякий случай оставлю
Private cond1 As Condition
Private cond2 As Condition
Public Sub new(cond1 As Condition, cond2 As Condition)
Set Me.cond1 = cond1
Set Me.cond2 = cond2
End Sub
Public Function match(di As DocInfo) As Boolean
match = cond1.match(di) Or cond2.match(di)
End Function
End Class

Private Class TrueCondition As Condition
Public Function match(di As DocInfo) As Boolean
match = True
End Function
End Class

Private Class SimpleCondition As Condition
Private field As String
Private value As String
Public Sub new(field As String, value As String)
Me.field = field
Me.value = value
End Sub
Public Function match(di As DocInfo) As Boolean
match = di.Field(field) = value
End Function
End Class

'Ниже зарефакторенная функция Property Get DocInfoCollCount 

Private Function createCondition(exType As Integer, byForm As String, exKind As String) As Condition
Dim typeCond As Condition
Dim formCond As Condition
Dim kindCond As Condition

If exType = CONST_INNER Then
Set typeCond = New SimpleCondition("ExType", "InnerExecutors")
Elseif exType = CONST_OUTER Then
Set typeCond = New SimpleCondition("ExType", "OuterExecutors")
Else
Set typeCond = New TrueCondition()
End If

If byForm = CONST_ALLFORM Then
Set formCond = New TrueCondition()
Else
Set formCond = New SimpleCondition("form", byForm)
End If

If exKind = CONST_KINDEXECUTOR Or exKind = CONST_KINDCORRESPONDENT Then
Set kindCond = New SimpleCondition("ExIsCorr", exKind)
Else
Set kindCond = New TrueCondition()
End If

Dim cond As New AndCondition(typeCond, formCond)

Set createCondition = New AndCondition(cond, kindCond)

End Function

Public Function exists(exType As Integer, byForm As String, exKind As String) As Boolean
Dim cond As Condition
exists = False
Set cond = createCondition(exType, byForm, exKind)
Forall di In DocInfoColl
If cond.match(di) Then
exists = True
Exit Function
End If
End Forall
End Function

Public Function getDocInfoCollCount(exType As Integer, byForm As String, exKind As String) As Long
Dim cond As Condition
Dim count As Long
count = 0
Set cond = createCondition(exType, byForm, exKind)
Forall di In DocInfoColl
If cond.match(di) Then
count = count + 1
End If
End Forall
getDocInfoCollCount = count
End Function
 
13.03.2009
625
1
#5
Ну как-то так:
Код:
	Property Get DocInfoCollCount(ExType As Integer, ByForm As String, ExKind As String, StopAtFirst As Boolean) As Long '---- ExType - вид исполнителя, ByForm - форма
... ' здесь проверка входных параметров

Dim searchCondition List As String
' вид исполнителя
If ExType=CONST_INNER Then 
searchCondition("ExType")="InnerExecutors" 
Elseif ExType=CONST_OUTER Then
searchCondition("ExType")="OuterExecutors"
End If
' форма
If ByForm<>CONST_ALLFORM Then
searchCondition("form") = ByForm 
End If

If ExKind=CONST_KINDEXECUTOR Or ExKind=CONST_KINDCORRESPONDENT Then
searchCondition("ExIsCorr") = ExKind 
End If

Forall DI In DocInfoColl
If isConditional( DI , searchCondition ) Then
DocInfoCollCount = DocInfoCollCount + 1
If StopAtFirst Then Exit Property
End If
End Forall
End Property

Private Function isConditional( DI As Variant , searchCondition List As String ) As Boolean
isConditional = True
Forall condition In searchCondition
If DI.Field( Listtag(condition) ) <> condition Then
isConditional = False
Exit Function
End If
End Forall
End Function
измените Variant на правильный тип DI.
welcome
 
D

Darker

#6
turumbay
то, что надо! Спасибо!
Yakov, работает только для двух операндов условия, а так, как концепция вполне сойдет! Спасибо тоже!
 

lmike

нет, пердело совершенство
Lotus team
27.08.2008
6 599
277
#7
Если в List записать доки ваше приложение скорее всего умрет, от не хватки памяти. плохой вариант хранить нотес документы в листе.
рефы - это не обязательно сами доки (я нигде этого не утверждал), это может быть и "контролирующий" объект (кот. по юниду, или вьюшному ключу, вытащит значения из дока, или проведёт сравнение)
если посмотреть на код выше - он, возможно, так и делает
 
Статус
Закрыто для дальнейших ответов.