ОБСУЖДЕНИЕ

Просуммировать элементы нескольких массивов

12 ответов 6,9 тыс.
AI-выжимка обсуждения скоро

Краткие тезисы обсуждения со ссылками на ключевые ответы появятся здесь.

Автор темы
Задача следующая
Имеется около 500 документов, что мы делаем,
Берем два документа, вычитываем значения из полей (обозначены как A(53)) и загоняем их в массив, получаем d1_1 и d2_1.
Теперь нужно каждое значение массива сложить друг с другом (d1_1(1) + d2_1(1) и так до самого последнего), получаем новый массив, например d3
И так по всем 500 доков

Если есть более короткое решение, подскажите.

Примерный код
Код:
Sub Click(Source As Button)
Dim A(53) As String	
A(53)="b_54"
A(52)="b_53"
A(51)="b_52"
A(50)="b_51"
A(49)="b_50"
A(48)="b_49"
A(47)="b_48"
A(46)="b_47"
A(45)="b_46"
A(44)="b_45"
A(43)="b_44"
A(42)="b_43"
A(41)="b_42"
A(40)="b_41"
A(39)="b_40"
A(38)="b_39"
A(37)="b_38"
A(36)="b_37"
A(35)="b_36"
A(34)="b_35"
A(33)="b_34"
A(32)="b_33"
A(31)="b_32"
A(30)="b_31"
A(29)="b_30"
A(28)="b_29"
A(27)="b_28"
A(26)="b_27"
A(25)="b_26"
A(24)="b_25"
A(23)="b_24"
A(22)="b_23"
A(21)="b_22"
A(20)="b_21"
A(19)="b_20"
A(18)="b_19"
A(17)="b_18"
A(16)="b_17"
A(15)="b_16"
A(14)="b_15"
A(13)="b_14"
A(12)="b_13"
A(11)="b_12"
A(10)="b_11"
A(9)="b_10"
A(8)="b_9"
A(7)="b_8"
A(6)="b_7"
A(5)="b_6"
A(4)="b_5"
A(3)="b_4"
A(2)="b_3"
A(1)="b_2"
A(0)="b_1"	
Dim ws As New NotesUIWorkspace
Dim uiview As NotesUIView
Dim view As NotesView
Dim doc As NotesDocument
Set uiview = ws.CurrentView
Set view = uiview.View
Set b = view.AllEntries

' открываем первый документ
'создаем массив на число элементов = числу полей
'забиваем этот массив значениями, переходим к следующему документу
'забиваем новый массив значениями и суммируем с предыдущим, переходим к следующему документу
'
For n=1 To b.count

Set doc = view.GetNthDocument(n)
Forall A1 In A
c = doc.GetItemValue(A1)
d1 = d1 & ";" & c(0)
End Forall
d1_1 = Split(d1,";") ' массив первых значений
'		Stop		

Set doc = view.GetNthDocument(n+1)
Forall A1 In A
c = doc.GetItemValue(A1)
d2 = d2 & ";" & c(0)
End Forall
d2_1 = Split(d2,";") ' массив следующих значений
Print "документ " & n
n = n+1
If n > b.count Then
Exit Sub
End If
d1_1 = ""
d2_1 = ""
d1 = ""
d2 = ""
'		Stop		

Next
Stop
End Sub
 
Если имена полей такие, какие указаны, то их можно в цикле получить.
Код:
for i = 1 to 54
c = doc.GetItemValue("b_" + Cstr(i))
d1 = d1 & ";" & c(0)
next
 
первыйже вопрос - почему поля отдельные а не списочные с множество значений
тогда не надо былобы загонять в массив
стоит вообще пойти от задачи - зачем это всё нужно делать?
 
allex

Код:
Dim A list as integer
-- тут забиваем лист нулями с тагами=имя поля
for i = 1 to 53
A("b_" + cstr(i) ) = 0
next

....

Set doc = view.getfirstdocument
while not doc is nothing
forall x in A
A( listtag(x) ) = x + doc.getitemvalue( listtag(X) )(0)
next

... 
-- тут имеем готовій лист по именам полей с итоговіми значениями по всем документам
set doc = view.getnextdocument(doc)
wend

я так понимаю раз сумируем, значит тип поля - интеджер или куренси?
p/s/ писал прямо тут, так шо могут біть ошибки
 
делаем вьюшку с выводом в колонку массива (спсок полей)
бежим по вьюшке, суммируем массивы (columnValues)

либо (вывести в колонку просто текст из контектации полей с раделителями ";")
в этом случае можем сделать еще такую мульку :)
в поле дока
list:=@DbColumn("":"";"";"test";1);
test:=@ReplaceSubString(@Implode(list;{+});";";{:});
@Eval(test)

по вскусу можно заменить на @DbLookup
работает (я проверял)
 
делаем вьюшку с выводом в колонку массива (спсок полей)
бежим по вьюшке, суммируем массивы (columnValues)
в документе 54 поля, и это еще не самая большая форма.
При подсчете можно будет на полдня уходить пить кофе
 
я спросил про задачу - вы шифруетесь :)

кофе пить не прийдется (вьшка считается один раз, потом апдейтится)
предкомпиленые строки работают вразы быстрее чем LS!
и доступ к колумнвалью - быстрей доступа к полям через инстанс дока
 
Страшный код.... :) :)

Учитывая что используется getNthDocument, действительно можно уходить пить кофе на пол-дня. Если поменять на getFirst getNext то такой код должен выполняться в течении 10 секунд, не более.

allex, советую взять код морфеуса и не извращатся. Если имена полей отличаются больше чем циферкой индекса, то массив имен вполне прокатит и из вашего варианта.
 
Развивая мысль Imike :
делаем вьюшку с выводом в колонку массива (спсок полей)
бежим по вьюшке, суммируем массивы (columnValues)


все гут, только бежать наверное никуда не надо, колонка должна быть суммирующей, на основе вида строим навигатор, далее
set entry=nav.getLast(не getlastdocument) и тупо считываем суммы
 
Развивая мысль Imike :
делаем вьюшку с выводом в колонку массива (спсок полей)
бежим по вьюшке, суммируем массивы (columnValues)


все гут, только бежать наверное никуда не надо, колонка должна быть суммирующей, на основе вида строим навигатор, далее
set entry=nav.getLast(не getlastdocument) и тупо считываем суммы
в тоталах, увы, массивы не хранятся
и формулу для подсчета, без перебора, я тоже указал (ниже)
правда формулы более ограничены по объему данных (в этом случае), но массивы 500х60 циферок м.б. и потянут ;)

Страшный код.... :) :o

Учитывая что используется getNthDocument, действительно можно уходить пить кофе на пол-дня. Если поменять на getFirst getNext то такой код должен выполняться в течении 10 секунд, не более.

allex, советую взять код морфеуса и не извращатся. Если имена полей отличаются больше чем циферкой индекса, то массив имен вполне прокатит и из вашего варианта.
поля воще можно получать как массив из дока и хеш составлять по фильтру с like (типа: if name like "a_???")
но повторюсь - LS со стрингами ну очень неоптимально работает и получение полей из дока - больше времени занимает, чем просто колумнвалью (уже скомпилёный - хоть стринг, хоть массив)
 
Наверное я не совсем грамотно выразился или не совсем правильно понял задачу (уы мне), я имел ввиду что для суммирования 53 полей документов надо построить вью с 53 колонками с тоталями и потом считать последнюю строку. Строительство такого вью еще тот мартышкин труд, но скорость заполнения итогового массива будет значительно выше предыдущих решений. Решение не гибкое, как и любое решение по максимальной оптимизации по скорости.
 
ммм... простите....
а можно сделить так....
замести массив нужных документов... думаю работать с ним будет быстрей чем с видом...
ну а потом гонять по этому массиву доков и суммировать таким способом... ну (писали выше)
Код:
forall x in A
A( listtag(x) ) = x + doc.getitemvalue( listtag(X) )(0)
next

Или это все глупости?
 

Статистика тем

Создано
allex,
Последний ответ от
NickProstoNick,
Ответы
12
Просмотры
6 885