Работа со справочниками

LuMee

Well-known member
02.05.2006
477
0
#1
Предположим, что имеются 2 сущности:
1. "Документ" - просто некий документ в организации, имеющий определенный тип: приказ, служебная записка и т.п.
2. "Тип документа" - справочник, представляющий собственно тип, помимо названия характеризующийся еще рядом свойств.
В реляционной базе данных связь между ними описывалась бы просто: "Документ" имел бы поле, содержащее id соотв. "Типа..". Вопрос в том, как лучше это сделать в Lotus?
Пришло в голову:
1. в одном из полей "Документа" хранить название (строкой) соотв. "Типа..", потом по этой строке при необходимости находить тип и выбирать нужные свойства
2. завести у "Типа.." дополнительное поле - какой-нибудь номер, который записывать в поле "Документа"
3. в "Документе" хранить UNID соотв. "Типа..." (кстати, как правильно UNID записать в текстовое поле, выбрав из вью "Тип.."?)
4. сделать "Документ" ответом на "Тип..." - очень не хотелось бы, ибо возникнет ряд сложностей.
Очень хотелось бы услышать советы и коментарии профессионалов.
 

LuMee

Well-known member
02.05.2006
477
0
#2
Сразу сходу еще один вопрос. Допустим, я решаю хранить некий код "Типа..." (какой бы то ни было). Соответственно, на форме "Документа" должно показываться название этого типа, в то время, как реально должен сохраняться именно код.
Название можно показывать с помощью Calculated-поля (перед сохранением подсовывать ему пустую строку, чтобы место не занимал), а поле с кодом "Типа..." сделать вычисляемым и скрытым. Вопрос в том, как организовать выбор. Идеальным вариантом было бы что-то вроде @PickList, только с возможностью выбора только одного значения. Причем выбираться должен документ, из которого я впоследствии вытащу нужное поле. Вот только все функции типа PickList'а подразумевают возможноть выбора нескольких значений, что не годится...
 

LuMee

Well-known member
02.05.2006
477
0
#3
Сразу сходу еще один вопрос. Допустим, я решаю хранить некий код "Типа..." (какой бы то ни было). Соответственно, на форме "Документа" должно показываться название этого типа, в то время, как реально должен сохраняться именно код.
Название можно показывать с помощью Calculated-поля (перед сохранением подсовывать ему пустую строку, чтобы место не занимал), а поле с кодом "Типа..." сделать вычисляемым и скрытым. Вопрос в том, как организовать выбор. Идеальным вариантом было бы что-то вроде @PickList, только с возможностью выбора только одного значения. Причем выбираться должен документ, из которого я впоследствии вытащу нужное поле. Вот только все функции типа PickList'а подразумевают возможноть выбора нескольких значений, что не годится...
Эм, тут погорячился.. Невнимательно док почитал, во всем уже разобрался. Но архитектурный вопрос, поднятый в первом посте, еще открыт
 
30.05.2006
1 345
11
#4
Допустим, я решаю хранить некий код "Типа..." (какой бы то ни было). Соответственно, на форме "Документа" должно показываться название этого типа, в то время, как реально должен сохраняться именно код.
RTFM
CheckBox. C алиасами. Если значение/алиас статические - то просто защиваются в форму. Либо - вычисляются по формуле (выражение типа: FldTitle + "|" + FldAlias )
 

LuMee

Well-known member
02.05.2006
477
0
#5
RTFM
CheckBox. C алиасами. Если значение/алиас статические - то просто защиваются в форму. Либо - вычисляются по формуле (выражение типа: FldTitle + "|" + FldAlias )
Пока сделал так: есть поле DocTypeName - название типа документа, поле DocTypeId - код типа документа (хранит соотв. UNID "Типа..."). Оба вычисляемые, второе - скрытое. Ну и хотспот для выбора типа (с помощью PickListCollection). UNID выбранного "Типа..." заносится в DocTypeId, а для DocTypeName в качестве значения повесил код:
Код:
id:= DocTypeId;
@If(
id = "";
"не выбран";

@GetDocField(id; "DocumentTypeName") <-- выбираю поле "Типа...", содержащее его название
)
Перед сохранением документа (на Querysave) тупо убиваю DocTypeName с помощью NotesDocument.RemoveItem().
 

LuMee

Well-known member
02.05.2006
477
0
#6
Еще такой вопрос: можно ли каким-то образом создать документ-ответ, не выделяя ни одного "отвечаемого" документа? Т.е. требуется сделать так, чтобы документ-ответ создавался, даже если ни одного документа не выделено, при этом он бы по умолчанию являлся ответом на некий документ, берущийся из определенного представления. Пытался сделать примерно таким образом на Queryopen (AllSampleForms - представлние, из которого берется дефолтный документ):
Код:
Sub Queryopen(Source As Notesuidocument, Mode As Integer, Isnewdoc As Variant, Continue As Variant)
Dim workSpace As New NotesUIWorkspace
Dim db As NotesDatabase
Dim allSampleForms As NotesView
Dim firstDoc As NotesDocument

If (IsNewDoc = True) Then	
Set db = workSpace.CurrentDatabase.Database
Set allSampleForms = db.GetView("AllSampleForms")
Set firstDoc = allSampleForms.GetFirstDocument
Call Source.Document.ReplaceItem("$REF", firstDoc.UniversalID)
End If

Continue = True
End Sub
Была еще мысль сделать документ обычным, не ответом, а в ходе редактирования или по Querysave добавлять в него поле $REF - он ведь тогда будет считаться ответным, так?
 
30.05.2006
1 345
11
#7
Мудришь..
1.Удаление поля в QuerySave ничего не гарантирует. Формулы полей пересчитываются после QuerySave (RTFM!) и поле может возродиться. Делай временные поля CFD или удаляй их из формулы другого поля, расположенного ниже/правее
2.Не лезь с грязными ногами в $REF (для этого есть метод doc.MakeResponse pdoc RTFM!!), у тебя оно текстовое получается
3.PickList для выбора единственного значения из одного варианта - эт крутА. Нечеловеческий интерфейс
 

LuMee

Well-known member
02.05.2006
477
0
#8
Мудришь..
1.Удаление поля в QuerySave ничего не гарантирует. Формулы полей пересчитываются после QuerySave (RTFM!) и поле может возродиться. Делай временные поля CFD или удаляй их из формулы другого поля, расположенного ниже/правее
Мудрю жестоко :) Про поле и Querysave уже сам задумался. Вот только насчет CFD - они разве не один раз вычисляются (при отображении документа)?
2.Не лезь с грязными ногами в $REF (для этого есть метод doc.MakeResponse pdoc RTFM!!), у тебя оно текстовое получается
Согласен, про MakeResponse подзабыл... Вот только применим ли данный метод к документу, который просто документ, а не ответ? И потом, все равно интересно, как правильно засовывать в поля документа UNID'ы, чтобы они UNID'ами оставались (вероятно, "Документ" будет участвовать в нескольких иерархиях). Просто достаточно в LotusScript заделать что вроде:
Код:
doc.MyUnidField = otherDoc.UniversalID
или надо хитрее?
3.PickList для выбора единственного значения из одного варианта - эт крутА. Нечеловеческий интерфейс
А какими еще средствами можно выбрать какой-то документ из вью (один причем)? Мудрить с ComboBox'ом и алиасами видимо будет непросто: не приходит в голову простая формула, которая выдернет набор значений вида "SomeDocField | UNID". Разве что с @DbColumn и циклами извращаться.. Или можно обойтись еще одной вью, со столбцом с такой формулой:
Код:
DocTypeName + "|" + @Text(@DocumentUniqueID))
З.Ы. Жаль дома лотус не стоит, до вторника не попробую...
 
30.05.2006
1 345
11
#9
Мудрю жестоко :) Про поле и Querysave уже сам задумался. Вот только насчет CFD - они разве не один раз вычисляются (при отображении документа)?
Не один (иногда это - проблема), а при каждом Recalculate и даже после Validation (см. соотв свойство поля)
Согласен, про MakeResponse подзабыл... Вот только применим ли данный метод к документу, который просто документ, а не ответ? И потом, все равно интересно, как правильно засовывать в поля документа UNID'ы, чтобы они UNID'ами оставались (вероятно, "Документ" будет участвовать в нескольких иерархиях). Просто достаточно в LotusScript заделать что вроде:
Код:
doc.MyUnidField = otherDoc.UniversalID
или надо хитрее?
Смотря чем эти ссылки будут использоваться. Для формул/скриптов подойдет и текст (UniversalID - text). А вот что-б отобразить иконочкой на форме и иерархией во вьюхе - тип д.б. правильным. Правильный тип дает MakeResponse. Если надо несколько иерархий - перекладывай $REF в другой item (методом CopyItem, а не копированием значения! иначе опять будет "text")
А какими еще средствами можно выбрать какой-то документ из вью (один причем)? Мудрить с ComboBox'ом и алиасами видимо будет непросто: не приходит в голову простая формула, которая выдернет набор значений вида "SomeDocField | UNID". Разве что с @DbColumn и циклами извращаться.. Или можно обойтись еще одной вью, со столбцом с такой формулой:
Код:
DocTypeName + "|" + @Text(@DocumentUniqueID))
З.Ы. Жаль дома лотус не стоит, до вторника не попробую...
Можно и так
 

LuMee

Well-known member
02.05.2006
477
0
#10
Смотря чем эти ссылки будут использоваться. Для формул/скриптов подойдет и текст (UniversalID - text). А вот что-б отобразить иконочкой на форме и иерархией во вьюхе - тип д.б. правильным. Правильный тип дает MakeResponse. Если надо несколько иерархий - перекладывай $REF в другой item (методом CopyItem, а не копированием значения! иначе опять будет "text")
Спасибо, буду пробовать :)
 

LuMee

Well-known member
02.05.2006
477
0
#12
Тут по ходу вопрос успел народиться (все не успевал дойти-задать). Если делать ComboBox, как было предложено в позапрошлом посте - UNID ведь в виде текста прийдет, так? Опять получается, что PickList сподручнее будет (пока что его оставил)... Хотя, конечно, можно по этому текстовому UNIDу вытаскивать документ, делаться его ответом, а потом в поле-ComboBox засовывать значение $REF методом CopyItem. Запутанно :)
 
30.05.2006
1 345
11
#13
Если делать ComboBox, как было предложено в позапрошлом посте - UNID ведь в виде текста прийдет, так? Опять получается, что PickList сподручнее будет (пока что его оставил)... Хотя, конечно, можно по этому текстовому UNIDу вытаскивать документ, делаться его ответом, а потом в поле-ComboBox засовывать значение $REF методом CopyItem.
А из PickList - не текст?
Вообще - что-то не то делаешь. Чувствуются СУБДшные привычки. А Domino-е они вредны. В Домине нет ссылочной целостности; в Домине типична избыточность; Домине противопоказана (как правило) нормализация. Так что пиши в док-т значение, а не ссылку на словарный документ.
Нет, есть, конечно исключительные случаи... Впрочем, ты о своей задаче не докладывал
 

LuMee

Well-known member
02.05.2006
477
0
#14
А из PickList - не текст?
Вообще - что-то не то делаешь. Чувствуются СУБДшные привычки. А Domino-е они вредны. В Домине нет ссылочной целостности; в Домине типична избыточность; Домине противопоказана (как правило) нормализация. Так что пиши в док-т значение, а не ссылку на словарный документ.
Нет, есть, конечно исключительные случаи... Впрочем, ты о своей задаче не докладывал
PickListCollection имелся ввиду :) Он возвращает коллекцию (из одного в моем случае документа), которую и пользую.
Насчет СУБДшных привычек - это да, всю жизнь с ними возился, а тут вдруг за Лотусом оказался. Собссно, потому топик и завел - было интересно, как в принципе такие вещи правильно делать.
От словарного документа ("Тип документа") отказываться неудобно имхо, т.к. помимо собственно названия он хранит еще ряд параметров, описывающих, что можно делать с документом данного типа.
 
30.05.2006
1 345
11
#15
От словарного документа ("Тип документа") отказываться неудобно имхо, т.к. помимо собственно названия он хранит еще ряд параметров, описывающих, что можно делать с документом данного типа.
Никто отказываться и не заставляет. Но поскольку в Домине нет и транзакции (и не может быть! В действительно распределенной среде, под которую заточена Домина, она невозможна), нет никакой гарантии, что по ссылке ты найдешь тот документ, который ожидаешь (или вообще что-то найдешь). Поэтому (нарушая 2ю нормальную форму) после выбора позиции в словаре в док-т пишем не ссылку, а значения из словаря. Или, если очень хочется, то и другое
 

LuMee

Well-known member
02.05.2006
477
0
#16
Никто отказываться и не заставляет. Но поскольку в Домине нет и транзакции (и не может быть! В действительно распределенной среде, под которую заточена Домина, она невозможна), нет никакой гарантии, что по ссылке ты найдешь тот документ, который ожидаешь (или вообще что-то найдешь). Поэтому (нарушая 2ю нормальную форму) после выбора позиции в словаре в док-т пишем не ссылку, а значения из словаря. Или, если очень хочется, то и другое
Как я отмечал, "Тип документа" определяет допустимые для "Документа" действия. Т.е., в зависимости от соотв. значений полей "Типа.." будут доступны или недоступны определенные действия над документом, а значит будут скрываться или показываться соотв. кнопки/хотспоты/action'ы. Значения этих полей тоже следует вынести в "Документ", или можно вытаскивать из "Типа..." на лету? Просто хочется избежать большой избыточности ("Типов..." всего несколько штук, а "Документов" - многие тысячи).
И такой вопрос: нет ли где вообще литературы, описывающей правильные и неправильные подходы к проектированию баз данных в Лотус? А то, чувствую, реляционные привычки будут сильно сбивать с курса.
 
30.05.2006
1 345
11
#17
..в зависимости от соотв. значений полей "Типа.." будут доступны или недоступны определенные действия над документом, а значит будут скрываться или показываться соотв. кнопки/хотспоты/action'ы. Значения этих полей тоже следует вынести в "Документ", или можно вытаскивать из "Типа..." на лету? Просто хочется избежать большой избыточности ("Типов..." всего несколько штук, а "Документов" - многие тысячи).
Какая избыточность? У меня в таких местах 1(2) multivalue поле со всем деревом разбора. Штук 10 ключей тебе хватит? А это по размеру немногим отличается от UNIDa (32 символа)
И такой вопрос: нет ли где вообще литературы, описывающей правильные и неправильные подходы к проектированию баз данных в Лотус? А то, чувствую, реляционные привычки будут сильно сбивать с курса.
нЭту... Здравый смысл и опыт. В твоем случае определись: как должны себя вести старые документы после правки справочника? По старому или по новому?
 

LuMee

Well-known member
02.05.2006
477
0
#18
У меня в таких местах 1(2) multivalue поле со всем деревом разбора. Штук 10 ключей тебе хватит? А это по размеру немногим отличается от UNIDa (32 символа)
Ммм, не совсем понял про дерево разбора...
В твоем случае определись: как должны себя вести старые документы после правки справочника? По старому или по новому?
Выяснилось только что, что одни должны вести себя по-новому, другие - по-старому :) В общем, тут полюбому придется хранить значения...