Поиск в List

Тема в разделе "Lotus - Программирование", создана пользователем Darker, 16 июл 2010.

Статус темы:
Закрыта.
  1. Darker

    Darker Гость

    Есть свойство для подсчета элементов списка по критерию
    Код (LotusScript):
    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
    Хотел не копипастить циклы, а закинуть в процедурку, так условие не знаю как передать в качестве "параметра"
    Нуждаюсь в рефакторинге
     
  2. lmike

    lmike нет, пердело совершенство
    Команда форума Lotus team

    Регистрация:
    27 авг 2008
    Сообщения:
    6.073
    Симпатии:
    299
    зависит от задачи, можно колекцию получать через DbSearch
    можно формировать List по ключам, элементом будет массив с рефами доков...
     
  3. Mady

    Mady Well-Known Member

    Регистрация:
    16 сен 2006
    Сообщения:
    66
    Симпатии:
    0
    можно формировать List по ключам, элементом будет массив с рефами доков...


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

    Yakov Гость

    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">
    Код (LotusScript):
    'Предполагаю, что где-то объявлен класс 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
     
  5. turumbay

    Регистрация:
    13 мар 2009
    Сообщения:
    625
    Симпатии:
    2
    Ну как-то так:
    Код (Text):
        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
     
  6. Darker

    Darker Гость

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

    lmike нет, пердело совершенство
    Команда форума Lotus team

    Регистрация:
    27 авг 2008
    Сообщения:
    6.073
    Симпатии:
    299
    рефы - это не обязательно сами доки (я нигде этого не утверждал), это может быть и "контролирующий" объект (кот. по юниду, или вьюшному ключу, вытащит значения из дока, или проведёт сравнение)
    если посмотреть на код выше - он, возможно, так и делает
     
Загрузка...
Статус темы:
Закрыта.

Поделиться этой страницей