Сравнение Полей

  • Автор темы BEST
  • Дата начала
B

BEST

#1
Столкнулась с проблемой. Необходимо в базе с гербовыми бланками найти и изменить статус n-ому количеству бланков в статусе "не использован" на "использован". Определить какой бланк нужно исправлять можно только по ссылкам в документах другой базы.
Во второй базе в документе отмечается номер бланка, который был использован (поле Doc_NumberBlank). SB_Number - поле с номером бланка в первой базе.
Написала агентик маленький, а там сравнение не отрабатывает, не знаю где может быть ошибка. Может кто подскажет?
Вот код:
Код:
Set db = ses.CurrentDatabase
Dim db_out As New NotesDatabase(db.Server,"kancler/dp_stamp.nsf")

Set Coll_Blank= db_out.Search({Form="StampBlank" & SB_StatusBlank ="Не использован" }, Nothing, 0)
Messagebox "Количество найденных документов =" + Cstr(Coll_Blank.Count), 48,"Внимание!"			 //Coll_Blank.Count=1660

Set db = ses.CurrentDatabase
Dim db_in As New NotesDatabase(db.Server,"kancler/dp_intern.nsf")
Set Coll_Doc = db_in.Search({Form="RKK" & Doc_NumberBlank !="" }, Nothing, 0)
Messagebox "Количество найденных документов =" + Cstr(Coll_Doc.Count), 48,"Внимание!"			 //Coll_Doc.Count=106
k=0
For i = 0 To Coll_Doc.Count -1
Set DocRkk = Coll_Doc.GetNthDocument(i+1)
For j = 0 To Coll_Blank.Count -1
Set DocBlank = Coll_Blank.GetNthDocument(j+1)										 
[b]If DocRkk.Doc_NumberBlank(0) = DocBlank.SB_Number(0) Then[/b]	 //мне кажется что ошибка где-то здесь(
k=k+1																				 //k=0, хотя там эти совпадения присутствуют (проверено)
End If
Next
Next

Messagebox "Количество найденных документов =" + Cstr(k), 48,"Внимание!"
 

morpheus

скриптописец
07.08.2006
3 915
1
#2
1. Не использовать конструкцию GetNthDocument, юзайте GetNextDocument
2. Типы полей совпадают?
3. В дебаггере что видно?
 

Мыш

Lotus team
12.02.2008
1 099
10
#3
Возможно наличие разного числа пробелов (визуально фиг заметишь) или вообще "левых" символов. И еще про регистр символов не забудьте. Ну и традиционно - совпадающие визуально символы англ. и рус. алфавитов...
Предлагаю вывести значения полей в файл и затем посмотреть в HEX'ах.
 

lmike

нет, пердело совершенство
Lotus team
27.08.2008
6 601
277
#4
как я понял - стоит задача подсчета одинаковых значений, дык нафига такой код?
бежим по коллекциям, собираем в
Код:
Dim values List As Long
s=Cstr(val) 'можно бежать по энтрисам - где в колонках уже стринги
if IsElement(values(s)) Then values(s)=values(s)+1:Else values(s)=1
а тут... - цикл в цикле, да еще последовательный перебор (бр-р-р)
 

VladSh

начинающий
Lotus team
11.12.2009
1 277
6
#5
GetNthDocument на данную проблему не влияет, а влияет на скорость перебора доков коллекции. Действительно лучше использовать GetNextDocument.

BESTыжая
Код:
For i = 0 To Coll_Doc.Count -1
Set DocRkk = Coll_Doc.GetNthDocument(i+1)
можно было бы заменить на
Код:
For i = 1 To Coll_Doc.Count
Set DocRkk = Coll_Doc.GetNthDocument(i)
код немного бы упростился.

Предположу, что проблема в логике - Вы сравниваете 1-й док из одной коллеции с 1-м из другой, и т.д., а такого соответствия никогда не будет.
Надо взять одну коллекцию, проходя брать док, а по нему вытягивать коллекцию документов, - Вы говорите, что они по "ссылке" связаны, вот и ищите "по ней". Операция долгая... я бы для поиска связанных доков использовал поиск по виду.
Т.е. получится:
- поиск коллекции основных документов
- цикл по ним; в цикле:
--- поиск коллекции связанных (по виду) для основного документа;
--- обработка коллекции связанных.
Ну или что-то типа того. Можно делать обратный поиск, но это смотря какая задача.. Лучше делать так, чтобы в цикле по максимуму сократить количество поисков связанных документов.
 

lmike

нет, пердело совершенство
Lotus team
27.08.2008
6 601
277
#6
ну и то что коллеги перечислили выше
 
B

BEST

#7
1. Не использовать конструкцию GetNthDocument, юзайте GetNextDocument
2. Типы полей совпадают?
3. В дебаггере что видно?

GetNextDocument не срабатывает - ошибку пишет
Типы полей совпадают - text


Добавлено:
Возможно наличие разного числа пробелов (визуально фиг заметишь) или вообще "левых" символов. И еще про регистр символов не забудьте. Ну и традиционно - совпадающие визуально символы англ. и рус. алфавитов...
Предлагаю вывести значения полей в файл и затем посмотреть в HEX'ах.


Код состоит из 7 цифр без пробелов и символов, я так думаю что все эти варианты отпадают

Насчет подсчета - это просто упрощенный вариант, чтобы не захламлять код. В оригинале if выглядит так:
If DocRkk.Doc_NumberBlank(0) = DocBlank.SB_Number(0) Then
k=k+1
Call DocBlank.PutInFolder("Настройка \ Анализ и корректировка док-тов")
Call DocBlank.ReplaceItemValue("SB_StatusBlank", "Использован")
Call DocBlank.ReplaceItemValue("status_key", "19")
Call DocBlank.Save(True, False)
End If
 

VladSh

начинающий
Lotus team
11.12.2009
1 277
6
#8
GetNextDocument не срабатывает - ошибку пишет
Направильно готовите. См. хэлп, там конструкция цикла другая.

Добавлено: И, да, ещё раз, - ваша ошибка не в GetNthDocument.

Добавлено (2):
Эту строку убрал бы:
Код:
Call DocBlank.ReplaceItemValue("SB_StatusBlank", "Использован")
лучше прописывать числовой код, а надпись выводить в интерфейсе, на форме.
 

morpheus

скриптописец
07.08.2006
3 915
1
#9
Добавлено: И, да, ещё раз, - ваша ошибка не в GetNthDocument.
подтверждаю, не в нём, привел как п1 потому что бросилось в глаза

дополнительно, попробуйте (если регистр не важен)

If Trim(lcase(DocRkk.Doc_NumberBlank(0))) = Trim(lcase(DocBlank.SB_Number(0) )) Then

+ что показывает дебагер???
 

VladSh

начинающий
Lotus team
11.12.2009
1 277
6
#10
If Trim(lcase(DocRkk.Doc_NumberBlank(0))) = Trim(lcase(DocBlank.SB_Number(0) )) Then
по 2 действия со стороками (а действия со строками гораздо тяжелее работают), не лучше ли:

Код:
If Val(DocRkk.GetItemValue("Doc_NumberBlank")(0)) = Val(DocBlank.GetItemValue("SB_Number")(0)) Then
 
B
#11
GetNthDocument на данную проблему не влияет, а влияет на скорость перебора доков коллекции. Действительно лучше использовать GetNextDocument.

BESTыжая
Код:
For i = 0 To Coll_Doc.Count -1
Set DocRkk = Coll_Doc.GetNthDocument(i+1)
можно было бы заменить на
Код:
For i = 1 To Coll_Doc.Count
Set DocRkk = Coll_Doc.GetNthDocument(i)
код немного бы упростился.

Предположу, что проблема в логике - Вы сравниваете 1-й док из одной коллеции с 1-м из другой, и т.д., а такого соответствия никогда не будет.
Надо взять одну коллекцию, проходя брать док, а по нему вытягивать коллекцию документов, - Вы говорите, что они по "ссылке" связаны, вот и ищите "по ней". Операция долгая... я бы для поиска связанных доков использовал поиск по виду.
Т.е. получится:
- поиск коллекции основных документов
- цикл по ним; в цикле:
--- поиск коллекции связанных (по виду) для основного документа;
--- обработка коллекции связанных.
Ну или что-то типа того. Можно делать обратный поиск, но это смотря какая задача.. Лучше делать так, чтобы в цикле по максимуму сократить количество поисков связанных документов.

Насчет логики немного не понятно, я ведь сравниваю поле 1-го документа из 1-й коллекции с полем 1-го док-та из 2-ой коллекции, а не сами документы.
Ссылка заключается в том что в документе присутствует поле (Doc_NumberBlank) с номером бланка, который используется. Именно по этому полю я и пытаюсь их найти. Doc_NumberBlank !="" - здесь я и отбираю документы, которые связаны с гербовыми бланками. У меня получилось 2 коллекции документов с минимальным количеством док-тов в них. Это насколько я все понимаю, может где-то торможу, незнаю
 

lmike

нет, пердело совершенство
Lotus team
27.08.2008
6 601
277
#12
Насчет подсчета - это просто упрощенный вариант, чтобы не захламлять код. В оригинале if выглядит так:
здесь зависит от логики
итак:
- кол-во итераций - в вашем случае N*K (причем медленных)
- в случае последовательного перебора 2-х колекций - N+K + перебор листа (оптимизированный)

как формировать лист - это уже от деталей зависит
в лист должны попадать значения из меньшей коллекции (если они не одинаковые)

почему так - перебор в листе будет более эффективный (там поиск д.б. оптимизирован) - там хэш
 
13.03.2009
625
1
#13
а действия со строками гораздо тяжелее работают
насколько гораздо? :)
в указанном коде операции со строками занимают тысячные доли процента времени выполнения.
а вот оптимизация lmike сократит время выполнения в сто(!) раз: 1660*106 / ( 1660 + 106 ) ~ 100
 

VladSh

начинающий
Lotus team
11.12.2009
1 277
6
#14
на много, сравните
в указанном коде операции со строками занимают тысячные доли процента времени выполнения.
а вот оптимизация [lmike] сократит время выполнения в сто(!) раз.
Я предлагаю оптимизацию, которая сократит время выполнения в 1000 раз))) см. ниже.
Столкнулась с проблемой. Необходимо в базе с гербовыми бланками найти и изменить статус n-ому количеству бланков в статусе "не использован" на "использован". Определить какой бланк нужно исправлять можно только по ссылкам в документах другой базы.
Решение перебора коллекции в коллекции кривое "архитектурно".

На форме основного документа, в которой меняется поле, при/после сохранения сравнивайте старое и новое значение отслеживаемого вами поля, и если оно изменилось, ищите в другой базе связанные документы и меняйте их.
При таком подходе вы каждый раз будете работать адресно (менять только нужные документы), и никакие дополнительные агенты с переборами не будут нужны.
 
B
#15
Проблема в том, что так то оно и есть, просто в связи с обновлениями у нас где-то месяц не отрабатывала эта проверка в итоге смешались бланки которые действительно не использованы и те, которые использованы, но не изменили свой статус. Найти кривые бланки проблематично потому что обе базы очень большие, на счет оптимизации я не заморачивалась так как агент единоразовый - один раз отработает и под снос его можно.


Еще нашла ошибку дебагером, предполагаю, что из-за нее:
значение Val(DocBlank.GetItemValue("SB_Number")(0)) всегда равно 0.

При выборе (проверочной) коллекции (Set Coll_Blank= db_out.Search({Form="StampBlank" & SB_StatusBlank ="Не использован" & SB_Number="0040162" ) отрабатывает. При сравнении нет. Пробовала всеми выше перечисленными методами.
 

nvyush

Lotus team
22.04.2009
2 317
0
#16
BESTыжая
Проверьте внимательно названия полей. Если вместо DocBlank.GetItemValue("SB_Number")(0) будет DocBlank.GetItemValue("SB_Nunber")(0) или что ещё, Lotus не выдаст ошибки, а вернёт пустую строку.
 
B
#17
BESTыжая
Проверьте внимательно названия полей. Если вместо DocBlank.GetItemValue("SB_Number")(0) будет DocBlank.GetItemValue("SB_Nunber")(0) или что ещё, Lotus не выдаст ошибки, а вернёт пустую строку.


и проверяла, и копировала и вставляла, чтобы идентично было, ничего не помогает, походу не в этом дело

Добавлено:
BESTыжая
Проверьте внимательно названия полей. Если вместо DocBlank.GetItemValue("SB_Number")(0) будет DocBlank.GetItemValue("SB_Nunber")(0) или что ещё, Lotus не выдаст ошибки, а вернёт пустую строку.


и проверяла, и копировала и вставляла, чтобы идентично было, ничего не помогает, походу не в этом дело
 

lmike

нет, пердело совершенство
Lotus team
27.08.2008
6 601
277
#18
на счет оптимизации я не заморачивалась так как агент единоразовый - один раз отработает и под снос его можно.
а потом мы возмущаемся индусским кодом
если нет желания сделать "нормально" - лучше вообще не делать
 
B
#19
а потом мы возмущаемся индусским кодом
если нет желания сделать "нормально" - лучше вообще не делать
проблема не в том что нет желания, а в том что нет навыков, я то админ, а не программист lotus, поэтому для меня и этот агент не легко дается, да и возможностей
у меня не много, весь исходный код закрыт, открыты только базы с агентами и отчетами, да и принципы построения я не знаю, вот и приходится лезть в свойства, искать поля и делать предположения, чтобы хоть что-то сделать
 

lmike

нет, пердело совершенство
Lotus team
27.08.2008
6 601
277
#20
тематический админ должен разбираться в программировании, и потратить время на это - тоже обязан