Как переопределить кнопку DEL на View?

Тема в разделе "Lotus - Программирование", создана пользователем GROMILA, 10 апр 2004.

  1. GROMILA

    GROMILA Well-Known Member

    Регистрация:
    8 апр 2004
    Сообщения:
    297
    Симпатии:
    0
    Народ, это снова я и мои траблы.

    Ситуация: МАНАГЕР (есть все права) заходит на View
    и нечаянно жмет DEL+F9. И ему вываливается стандартный диалог.

    Вопрос: А как ему выдать мой диалог с крутой надписью:
    "Ты че делаешь, придурок, это же удалять ЗАПРЕЩЕНО."
    И еще оповестить при этом всех пользователей по почте в сети, что,
    дескать, спасайся кто может.

    Как навесить на событие DEL свой добавочный скрипт с диалогом?
     
  2. nor

    nor Гость

    Привет, Gromila.

    Во-первых, для опрделенного человека или группы людей, для которых запрещено удалять документы, тебе необходимо создать соответствующую группу в ACL базы данных, дать им уровень Manager и убрать привилегию Delete documents.
    Во-вторых, можно создать скрипт, реагирующий на событие удаления документов: Other - Database Resources - Database Script - Querydocumentdelete. В обработчике этого события нельзя пользоваться ф-ей MessageBox. Можно, например, написат следующее:

    <code>
    Print "Document deletion not allowed."
    Continue = False
    </code>

    Для решения проблемы, нужно тебе более подробно описать ситуационный момент.
     
  3. GROMILA

    GROMILA Well-Known Member

    Регистрация:
    8 апр 2004
    Сообщения:
    297
    Симпатии:
    0
    Правами не решить!

    Поясняю:
    есть куча документов в моей БД и куча представлений!!

    Задача:
    Только для представления View1, которое только для документов Form1 нужно перехватить калавишу DEL.
    Для всех остальных документов и представлений - НЕ НУЖНО.

    Пусть я не смогу вывести диалог, но КОД хотябы отменяющий это действие я могу как-то написать?
    плюс код, который еще что-нибудь сделает, например, писанет в другой документ пару ласковых.

    Спасибо.
     
  4. GROMILA

    GROMILA Well-Known Member

    Регистрация:
    8 апр 2004
    Сообщения:
    297
    Симпатии:
    0
    Приведу пример нужной мне обработки удаления

    Ситуация:
    Есть View1, отображающее 3 документа с полями (Сотрудник,Статус)

    Отображение View1:

    Код (Text):
           Сотрудник  Статус
    Документ1: Иванов     0
    Документ2: Петров     1
    Документ3: Сидоро     0
    Админ залазит на это представление и метит клавишей DEL все 3 документа.
    Потом жмет обновить (F9 или мышой или ....)

    Задание:
    Необходимо удалить документы где Статус=0
    если среди отмаркированных на удаление есть документы Статус=1, то
    - их не удалять
    - вывести на экран сообщение о попытке удалить БЕССМЕРТНЫХ сотрудников!
    - сделать запись в документ-журнал о том, что админ пытался мочить, но не замочил Петрова.
    - Петрову выслать уведомление по почте, что АДМИН имеет на него зуб.

    Вопрос:
    Помогите, люди добрые!
     
  5. nor

    nor Гость

    Привет, Gromila, еще раз.

    Я решил твою проблему. Следующий код проверен на работоспособность. Его необходимо записать в Other - Database Resources - Database Script. После компилирования и сохранения кода необходимо закрыть полностью соответствующую бд в designer и notes. Он выполняет следующее: при попытке удаления документов формы "temp1", статус которых "status = 1" из представления "temp1" 1. не удаляет эти документы, 2. выводится сообщение на экран о невозможности удаления документов, 3. формируется лог_сообщение, которое записывается в "документ-журнал" с указанием даты и имени персоны, которая пыталась удалить документы, 4. отсылается уведомление выбранным людям по потче с соответствующим сообщением (в моем случае уведомление отсылаетсяодному человеку).

    Код (Text):
    (Declaration)
    Type LogMsg
    msg As String
    doclink_unid As String 
    End Type

    Dim session As NotesSession
    Dim ws As NotesUIWorkspace
    Dim db As NotesDatabase
    Dim uidb As NotesUIDatabase
    Dim collection As NotesDocumentCollection
    Dim doc As NotesDocument
    Dim uiview As NotesUIView
    Dim view As NotesView
    Dim rtitem As NotesRichTextItem
    Dim rtitemStyle As NotesRichTextStyle
    Dim rtitemPStyle As NotesRichTextParagraphStyle
    Dim dateTime As NotesDateTime
    Dim log_msg() As LogMsg

    (Initialize)
    Sub Initialize

    Set session = New NotesSession
    Set ws = New NotesUIWorkspace
    Set db = session.CurrentDatabase   

    End Sub

    (Querydocumentdelete)
    Sub Querydocumentdelete(Source As Notesuidatabase, Continue As Variant)
    Dim n As Integer
    Dim msg As String
    Dim search_str As String
    Dim log_file As NotesDocument
    Dim collection_log_file As NotesDocumentCollection
    Dim dividing_line As Variant

    Set uidb = ws.CurrentDatabase
    Set uiview = ws.CurrentView
    Set view = uiview.View
    Redim log_msg(0)   
    log_msg(0).msg = "Лог-файл"
    log_msg(0).doclink_unid = ""

    If view.Name = "temp1" Then
    Set collection = uidb.Documents  
    For i = 1 To collection.Count
    Set doc = collection.GetNthDocument(i)  
    If doc.Form(0) = "temp1" And doc.status(0) = 1 Then
     Messagebox "Удаление 'БЕССМЕРТНЫХ' сотрудников запрещено."
     n = Ubound(log_msg)
     Redim Preserve log_msg(n + 1)
     log_msg(n + 1).msg = "Произведена попытка несанкционированного удаления профильного документа сотрудника."
     log_msg(n + 1).doclink_unid = doc.UniversalID
     Call SendLogFile("Попытка несанкционированного удаления документа", "sergey a petushkov", log_msg)  
     
     search_str = "Form = ""log"""
     Set collection_log_file = db.Search(search_str, Nothing, 0)
     Set log_file = collection_log_file.GetFirstDocument
     Set rtitem = log_file.GetFirstItem("log_msg")
     If rtitem.Type = RICHTEXT Then  
        Call rtitem.AppendText("Произведена попытка несанкционированного удаления профильного документа сотрудника. ")
        Call rtitem.AddNewLine(1)
        Call rtitem.AppendText("Выполнил: " + session.CommonUserName)
        Call rtitem.AddNewLine(1)
        Call rtitem.AppendText("Дата: " + Date$ + " / " + Time$)
        dividing_line = Evaluate("@Repeat(""- -""; 20)", log_file) 
        Call rtitem.AddNewLine(1)
        Call rtitem.AppendText(dividing_line(0))   
        Call rtitem.AddNewLine(1)
        Call log_file.Save(True, True)
     End If  
     
     Continue = False  
     
    End If
    Next
    End If

    End Sub

    (SendLogFile)
    Sub SendLogFile(subject As String, sendto As String, log_msg() As LogMsg)
    Dim maildoc As NotesDocument
    Dim doclink As NotesDocument   
    Dim dividing_line As Variant

    If sendto = "" Then sendto = session.CommonUserName

    Set maildoc = New NotesDocument(dB)
    maildoc.Form = "Memo"
    maildoc.Subject = subject
    maildoc.SendTo = sendto
    maildoc.Principal = db.Title

    Set rtitem = New NotesRichTextItem(maildoc, "Body")

    Set rtitemStyle = session.CreateRichTextStyle
    rtitemStyle.NotesColor = COLOR_DARK_BLUE
    rtitemStyle.FontSize = 8
    Call rtitem.AppendStyle(rtitemStyle)
    Call rtitem.AppendText(" " + db.Title )
    Call rtitem.AddNewLine(1)

    rtitemStyle.NotesFont = FONT_HELV
    rtitemStyle.NotesColor = COLOR_GRAY
    rtitemStyle.FontSize = 14
    rtitemStyle.Bold = True
    Set rtitemPStyle = session.CreateRichTextParagraphStyle
    rtitemPStyle.Alignment = ALIGN_CENTER
    Call rtitem.AppendParagraphStyle(rtitemPStyle)
    Call rtitem.AppendStyle(rtitemStyle)
    Call rtitem.AppendText(log_msg(0).msg)
    Call rtitem.AddNewLine(1)  
    rtitemStyle.FontSize = 10
    rtitemPStyle.Alignment = ALIGN_LEFT
    Call rtitem.AppendParagraphStyle(rtitemPStyle)
    Call rtitem.AppendStyle(rtitemStyle)
    Call rtitem.AppendText("Выполнил: " + session.CommonUserName)
    Call rtitem.AddNewLine(1)
    Call rtitem.AppendText("Дата: " + Date$ + " / " + Time$)
    Call rtitem.AddNewLine(1)

    rtitemStyle.NotesColor = COLOR_BLACK
    rtitemStyle.FontSize = 10
    rtitemStyle.Bold = False
    rtitemStyle.Underline = False
    Call rtitem.AppendStyle(rtitemStyle)

    For i = 1 To Ubound(log_msg)
    rtitemPStyle.Alignment = ALIGN_LEFT
    Call rtitem.AppendParagraphStyle(rtitemPStyle)
    Call rtitem.AddNewLine(1)
    Call rtitem.AppendText(log_msg(i).msg)  
    If log_msg(i).doclink_unid <> "" Then
    Call rtitem.AppendText(" Ссылка на документ: ")
    Set doclink = db.GetDocumentByUNID(log_msg(i).doclink_unid)
    If Not (doclink Is Nothing) Then Call rtitem.AppendDocLink(doclink, "Вы можете открыть документ, нажав на ссылку.")
    End If
    rtitemPStyle.Alignment = ALIGN_CENTER
    Call rtitem.AppendParagraphStyle(rtitemPStyle)
    dividing_line = Evaluate("@Repeat(""- -""; 20)", maildoc)  
    Call rtitem.AppendText(dividing_line(0))
    Next

    Call maildoc.Send(False)   

    End Sub
     
  6. GROMILA

    GROMILA Well-Known Member

    Регистрация:
    8 апр 2004
    Сообщения:
    297
    Симпатии:
    0
    Я по-другому переопределить нельзя?
    Ведь если таких View несколько, то код дичайший получится!
     
  7. Veselinka

    Veselinka Гость

    можно например, при дизане вьюхи - определять событие ее открытия QueryOpen и засовывать в переменные окружения SetEnvironmentVar - можно из этой вьюхи документы удалять или нет.

    А потом на событии qdd базы - просто проверять значение этой переменной - оно будет атрибутом текущей вьюхи.

    Я думаю есть еще 10 способов - сделать удаляемость атрибутом текущей вью и написать универсальный код события удаления, который не нужно будет модифицировать при изменении дизайна каких-то не относящихся к нему элементов. Принцип инкапсуляции.
     
  8. nor

    nor Гость

    GROMILA.
    :unsure:
    ПРОСТО убери неужную строку: If view.Name = "temp1" Then и соответствующий закрывающий элемент End If. (тогда уже Set uiview = ws.CurrentView Set view = uiview.View тебе тоже ненужны будут).
    ВСЕ! "Дичайшие" коды под каждую вью не надо писать. ;) Вопросы если есть - спрашивай.
     
  9. nor

    nor Гость

    Veselinka, хочу предствить тебе для критики код, который отправляет выделенные в представлнии документы в корзину и, при необходимости, восстанавливает документы. (аналог корзины в винде) - это по поводу твоего последнего сообщния.

    Код (Text):
    Sub DeleteSelectedDoc()

    If Not profile_ini Then Exit Sub

    Set dateTime = New NotesDateTime( "00/00/00" )
    Set collection = db.UnprocessedSearch("!@IsUnavailable(Form)", dateTime, 0)
    If collection.Count = 0 Then
    Messagebox "Выделите документы.", MB_OK + MB_ICONEXCLAMATION, title
    Exit Sub
    End If

    dialog_flag = Messagebox("Выделенные документы будут удалены." + Ustring$(2, 10) + "Продолжить?",_
    MB_YESNO + MB_ICONQUESTION, title)
    If dialog_flag = IDNO Then Exit Sub

    Call collection.StampAll("is_deleted", 1)
    Call collection.StampAll("deletion_date", Date$ + " / " + Time$)
    Call collection.StampAll("who_deleted", session.CommonUserName)
    Call collection.PutAllInFolder("Trash", False) 

    Call ws.ViewRefresh

    End Sub

    Sub UnDeleteSelectedDoc()

    If Not profile_ini Then Exit Sub

    Set dateTime = New NotesDateTime( "00/00/00" )
    Set collection = db.UnprocessedSearch("!@IsUnavailable(Form)", dateTime, 0)
    If collection.Count = 0 Then
    Messagebox "Выделите документы.", MB_OK + MB_ICONEXCLAMATION, title
    Exit Sub
    End If

    dialog_flag = Messagebox("Выделенные документы будут восстановлены." + Ustring$(2, 10) + "Продолжить?",_
    MB_YESNO + MB_ICONQUESTION, title)
    If dialog_flag = IDNO Then Exit Sub

    For i = 1 To collection.Count
    Set doc = collection.GetNthDocument(i)
    doc.is_deleted = 0
    doc.deletion_date = ""
    doc.who_deleted = ""
    Call doc.Save(True, True)
    Call doc.RemoveFromFolder("Trash")
    Next

    Call ws.ViewRefresh

    End Sub
     
  10. GROMILA

    GROMILA Well-Known Member

    Регистрация:
    8 апр 2004
    Сообщения:
    297
    Симпатии:
    0
    VASELINKA

    Назови 3 из них, плиз.
    Вешать обработку сразу на всю БД не хочется - плохо это, согласись!
     
  11. Veselinka

    Veselinka Гость

    <!--QuoteBegin-nor+12:04:2004, 21:23 -->
    <span class="vbquote">(nor @ 12:04:2004, 21:23 )</span><!--QuoteEBegin-->Veselinka, хочу предствить тебе для критики код, который отправляет выделенные в представлнии документы в корзину и, при необходимости, восстанавливает документы. (аналог корзины в винде) - это по поводу твоего последнего сообщния.

    Код (Text):
    Sub DeleteSelectedDoc()

    If Not profile_ini Then Exit Sub

    Set dateTime = New NotesDateTime( "00/00/00" )
    Set collection = db.UnprocessedSearch("!@IsUnavailable(Form)", dateTime, 0)
    If collection.Count = 0 Then
     Messagebox "Выделите документы.", MB_OK + MB_ICONEXCLAMATION, title
     Exit Sub
    End If

    dialog_flag = Messagebox("Выделенные документы будут удалены." + Ustring$(2, 10) + "Продолжить?",_
    MB_YESNO + MB_ICONQUESTION, title)
    If dialog_flag = IDNO Then Exit Sub

    Call collection.StampAll("is_deleted", 1)
    Call collection.StampAll("deletion_date", Date$ + " / " + Time$)
    Call collection.StampAll("who_deleted", session.CommonUserName)
    Call collection.PutAllInFolder("Trash", False) 

    Call ws.ViewRefresh

    End Sub

    Sub UnDeleteSelectedDoc()

    If Not profile_ini Then Exit Sub

    Set dateTime = New NotesDateTime( "00/00/00" )
    Set collection = db.UnprocessedSearch("!@IsUnavailable(Form)", dateTime, 0)
    If collection.Count = 0 Then
     Messagebox "Выделите документы.", MB_OK + MB_ICONEXCLAMATION, title
     Exit Sub
    End If

    dialog_flag = Messagebox("Выделенные документы будут восстановлены." + Ustring$(2, 10) + "Продолжить?",_
    MB_YESNO + MB_ICONQUESTION, title)
    If dialog_flag = IDNO Then Exit Sub

    For i = 1 To collection.Count
     Set doc = collection.GetNthDocument(i)
     doc.is_deleted = 0
     doc.deletion_date = ""
     doc.who_deleted = ""
     Call doc.Save(True, True)
     Call doc.RemoveFromFolder("Trash")
    Next

    Call ws.ViewRefresh

    End Sub
    [/quote]
    Я не совсем поняла твою логику о связи этого кода с моим замечанием.
    По-поводу этого кода могу сказать лишь, что 2ая процедура неоптимально написана - сильно не рекомендуется использовать обход коллекции методами getNthDocument(i), так как при взятии документа по индексу для каждого индекса происходит последовательный обход коллекции, то есть для коллекции из эн элементов происходит
    1+2+3+N-1 переборов элементов коллекции.

    Оптимальнее использовать GetNextDocument(doc).

    В остальном при беглом просмотре код не показался мне где-либо неправильным или не соответствующим описанной бизнес логике.

    Надо только добавить что во всех вью, в формуле селекции должно присутствовать условие непопадания во вьюхи документов с флагами удаления.

    А проще было бы включить флаг soft deletion на базе и сделать вьюху типа shared, contains deleted documents. И сделать всю эту логику стандартными механизмами нотес, для этого предназначенными.
     
  12. Veselinka

    Veselinka Гость

    GROMILA - по видимому ты меня не совсем понял. От написания логики контроля удаления на событии базы все равно не куда не денешься. Просто можно в этом коде получить текущую вью и по одному из атрибутов (именно этих атрибутов можно придумать с десяток) - в событии понимать - можно документы удалять или нет.

    Тогда при дизайне каждой новой вью можно будет определять именно для нее выбранный для валидации атрибут - удалять из этой вью или не удалять. И не трогать код события удаления в базе.

    Если интересуют навскидку примеры того, какой флаг можно поставить у вьюхи - как флаг удаляемости
    1) уже приведенный пример - проставление на QO вьюхи session.SetEnvironmentVar("delete","Yes\No")
    2) можно ввести нотацию именований для алиасов вьюхи - ну например ввести алиасы с постфиксом _del & _not, а на событии удаления if right(ws.currentView.View.Name,4)="_del" - Тогда удаляем иначе - делаем то что положено в этом случае
    3)пока в голову не приходит - а тратить времени на длительные раздумья по этой теме возможности не имею, что-нибудь придет в голову - напишу, хотя не вижу смысла в твоей просьбе привести 3 примера. Так как для достижения цели - решения задачи - тебе и одного бы хватило.
     
  13. nor

    nor Гость

    GROMILA, я в недоумении. Честное слово.
    Почему плохо вешать обработку на всю бд сразу? :) Тебе нужно было при удалении обрабатывать документы и в зависимости от значений полей документов и того, в каких представлениях они располагаются, разрешать или не разрешать удаление. Я все правильно понял? Нужно учитывать несколько редставлений? - Создай массив из них и включи его в обработчик.
    Или что тебе надо? Я так вообще ничего не понимаю уже. :) :blink: :blink:

    Veselinka. Я тебя тоже не понял. Зачем переменные окружения? (А если пользователь не обладает соответствующими правами для создания таких переменных, что тогда?) Зачем нотация наименований? Можно пользоваться объектом CurrentView, например. Можно передавать флаг через параметр вызываемой ф-ии, например.

    Насчет "кода, который отправляет выделенные в представлнии документы в корзину..." - я надеялся, что ты поделишься со мной своим аналогичным универсальным кодом: "универсальный код события удаления, который не нужно будет модифицировать при изменении дизайна каких-то не относящихся к нему элементов. Принцип инкапсуляции. " Меня это крайне заинтересовало.
    "По-поводу этого кода могу сказать лишь, что 2ая процедура неоптимально написана..." Я знаю про это. Но. В представлении для удаления мышкой обычно выделяют небольшое кол-во документов. Пусть даже выделили их 1000 или чуть более. Это самый невероятный случай. При этом разница в производительности кода моего цикла For и твоего будет стремиться к нулю, уверяю тебя. Свойство "soft deletion" конкретно для этой бд мне не подходит, т.к. все удаленные документы перемещаются в папку (запрос клиента) для подтверждение удаления "администратором" системы, по этой причине представление и тем более "shared" мне не подходит.
     
  14. GROMILA

    GROMILA Well-Known Member

    Регистрация:
    8 апр 2004
    Сообщения:
    297
    Симпатии:
    0
    Nor, я тоже хотел посмотреть на "Принцип инкапсуляции" вот и спрашивал про доп.пример.

    Просто я после других языкав не могу понять почему есть QuerySave и нет OnDelete
    Это так непривычно!

    А писать дикий IF в одном месте это как-то ГОМОЗДКО выглядит.

    Да, NOR, у меня еще одна проблема по поводу удаления появилась!
    Почему-то, когда я удаляю записи уже по Action (по батону) все типа чики-пики очистил, но потом после закрытия БД
    выскакивеает, скрывавшийся за всеми окнами диалог:
    Удалено столько -то записей!!! У меня версия 6.0, а моя же БД на 5.0 уже сей БОКС не выдает!
    Погано что этот диалог скрыт за окнами!!!!
     
  15. Veselinka

    Veselinka Гость

    Окей,
    примем в качестве флага идентифицирующего - удалять окументы из вью или неудалять - посфткс в имени вью 2 видов _not & _del

    Тогда событие удаления будет выглядеть следующим образом:


    Sub Querydocumentdelete(Source As Notesuidatabase, Continue As Variant)

    dim ws as new NotesUIWorkspace
    if right(ws.currentView.View.Name,4)="_not" then

    continue=false
    ' далее идет код рассылки жалоб и пр
    else

    Set coll=source.documents
    Set doc=coll.GetFirstDocument
    While Not doc Is Nothing
    Set ndoc=coll.GetNextDocument(doc)

    ' здесь вызывается функция генерации лога удаления документа

    Call doc.remove(True)
    Set doc=ndoc
    Wend


    end if

    End Sub

    Приведенный пример для добавления или модификации вьюхи НЕ ТРЕБУЕТ переписывания события удаления. Требуется лишь придерживаться нотации именований вьюх (можно именовать алиасы и анализировать их). То есть принцип инкапсуляции (когда все свойства и бизнес логика объекта являются его и только его свойствами и не влияют на другие объекты) выполнен.
     
  16. nor

    nor Гость

    Привет, Gromilla.
    Насчет втоей проблемы - никогда не встречал. Могу посоветовать следующее: открываешь File - Preferences - User Preferences - Additional Options. Там попоробуй поубирать опции типа "Display Window Menu", "Standart Dialog Box", etc. Я точно не знаю.
     
  17. mony_id

    mony_id Гость

    нАПИСАНИЕ СКРИПТА в событиях вида!!!!
    енто делается и работает
     
  18. GROMILA

    GROMILA Well-Known Member

    Регистрация:
    8 апр 2004
    Сообщения:
    297
    Симпатии:
    0
    mony_id

    А на какое событие это можно повесить?
    По-моему клавиша DEL не перехватывается - не нашел.
     
  19. Veselinka

    Veselinka Гость

    нету событий у вьюхи на удаление документов!
    ни в 5-ке ни в 6-ке. :p
     
  20. nor

    nor Гость

    посему слушайте меня :p
    событие удалния документов есть только у бд в целом
     
Загрузка...

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