B
beloff
Опять завелся какой то демон. Проблема кроется в том что скрипт написан на кнопку в форме, которая вызывается диалогбоксом, т.е. посмотреть дебагером не получится (кроме предпросмотра непосредственно этой формы из дизайнера вызвать её в клиент, но это не вариант, т.к. куча данных берется непосредственно из документа). Ситуация: БД персонал, оформление отпусков, попытка оформить новый отпуск вызывает ошибку invalid use of null в строке
ItemNumTmp = Arraygetindex(vArrCur, Cdat(vDatePeriod0)).
Я так понял что гемор именно с этой функцией (Arraygetindex), т.к. работает она через пень-колоду (встречал в нете). Смысл функции - взять индекс
выбранной даты в массиве, т.к. у человека который работает не первый год может быть куча отпускных периодов и нужно как-то оперировать с данными в массивах с этим индексом. Дополнительная проблема - не выявлена закономерность, т.к. на некоторых работает, на некоторых отказывается, на некоторых сначала отказывается, потом ни с того, ни с сего работает. Ломаю голову уже 3-й день. Может, переписать скрипт вставив вместо этой долбаной функции обычный цикл сравнения одного значения с каждым элементом массива. Вобщем, СОС, ай нид хэлп
<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">Sub OnAcceptChanges(Byval bNew As Boolean)
Dim StrTmp As String
Dim vNames(0 To 10) As String
Dim ItemNum As Long, i As Long, j As Long, k As Long
Dim vIndex As Variant, vArrCur As Variant, vArrCurCopy As Variant
Dim vDate0 As Variant, vDate1 As Variant
Dim vDatePeriod0 As Variant, vDatePeriod1 As Variant
Dim VacationLen As Long, ItemNumTmp As Long
Dim bRedim As Boolean, bCompens As Boolean
Dim ThisDoc As NotesDocument
Dim Wks As New NotesUIWorkspace
'On Error Goto errmsg
Call Wks.CurrentDocument.Refresh
Set ThisDoc = Wks.CurrentDocument.Document
'// Проверка полей, обязательных для заполнения
Dim str_listfields List As String
StrTmp = Lcase$(Wks.CurrentDocument.FieldGetText("VacKind"))
str_listfields("VacKind") = "Вид отпуска"
If StrTmp Like "*компенсац*" And Wks.CurrentDocument.FieldGetText("VacType")="Трудовой" Then
bCompens = True
Else
bCompens = False
str_listfields("VacBegin") = "Дата начала отпуска"
str_listfields("VacEnd") = "Дата окончания отпуска"
End If
If Lib_CheckMandatoryFields(Wks.CurrentDocument, str_listfields) = False Then Exit Sub
If ThisDoc.HideOrder(0) = "1" Then
vArrCur = ThisDoc.RC_VacType
If vArrCur(0) <> "" And Wks.CurrentDocument.FieldGetText("VacType") <> vArrCur(0) Then
Messagebox "Не допустимо предоставление и трудового и социального отпусков в одной записке.", 16, "Отпуск"
Exit Sub
End If
End If
If Not bCompens Then
vDate0 = Cdat(ThisDoc.GetItemValue("VacBegin")(0))
vDate1 = Cdat(ThisDoc.GetItemValue("VacEnd")(0))
End If
StrTmp = Wks.CurrentDocument.FieldGetText("VacLen")
If StrTmp <> "" And Not Isnumeric(StrTmp) Then
Messagebox "Неверно указана продолжительность отпуска.", 16, "Ошибка ввода"
Exit Sub
Elseif StrTmp = "" And Not bCompens Then
If Cdat(vDate1) >= Cdat(vDate0) Then
StrTmp = Cstr(vDate1 - vDate0)
Call ThisDoc.ReplaceItemValue("VacLen", StrTmp)
End If
End If
If Wks.CurrentDocument.FieldGetText("VacType") = "Трудовой" Then
If StrTmp = "" Then
Messagebox "Не задана продолжительность трудового отпуска.", 16, "Ошибка ввода"
Exit Sub
End If
i = Clng(StrTmp)
StrTmp = Wks.CurrentDocument.FieldGetText("VacPeriod")
If StrTmp = "" Or StrTmp = "-" Then
Messagebox "Не задан период трудового отпуска.", 16, "Ошибка ввода"
Exit Sub
End If
vDatePeriod0 = Cdat(Fulltrim(Strleft(StrTmp, "-")))
vDatePeriod1 = Cdat(Fulltrim(Strright(StrTmp, "-")))
If Not bCompens Then
If Cdat(vDate0)+i-1 > Cdat(vDate1) Then
Messagebox "Даты начала и окончания отпуска не согласуются с продолжительностью.", 16, "Ошибка ввода"
Exit Sub
End If
End If
VacationLen = i
vArrCur = ThisDoc.GetItemValue("RC_VacPeriodStart")
ItemNumTmp = Arraygetindex(vArrCur, Cdat(vDatePeriod0))
End If
' имена полей
vNames(0) = "Indexes"
vNames(1) = "RC_VacKind"
vNames(2) = "RC_VacType"
vNames(3) = "RC_VacPeriod"
vNames(4) = "RC_VacLen"
vNames(5) = "RC_VacBegin"
vNames(6) = "RC_VacEnd"
vNames(7) = "RC_VacOrder"
vNames(8) = "RC_VacCache"
vNames(9) = "RC_VacNotes"
vNames(10) = "RC_VacFlags"
' Определение номера текущей записи (редактирование/добавление), 0 - новая запись
StrTmp = Cstr(ThisDoc.GetItemValue("CurItem")(0))
If Not Isnumeric(StrTmp) Then ItemNum = 0 Else ItemNum = Clng(StrTmp)
If bNew Then ItemNum = 0
vIndex = ThisDoc.GetItemValue("Indexes")
If vIndex(0) <> "" And Not bCompens Then
vDatePeriod0 = ThisDoc.GetItemValue("RC_VacBegin")
vDatePeriod1 = ThisDoc.GetItemValue("RC_VacEnd")
For i = 0 To Ubound(vIndex)
If Isdate(vDatePeriod0(i)) And Isdate(vDatePeriod1(i)) Then
If (ItemNum-1) <> i And Not (Cdat(vDate1) < Cdat(vDatePeriod0(i)) Or Cdat(vDate0) > Cdat(vDatePeriod1(i))) Then
Messagebox "Заданный период пересекается с существующим: "+_
Format$(vDatePeriod0(i), "dd.mm.yyyy")+" - "+Format$(vDatePeriod1(i), "dd.mm.yyyy")+Chr$(10)+_
"( № "+Cstr(i+1)+" в списке )", 16, "Ошибка ввода"
Exit Sub
End If
End If
Next i
End If
If ItemNum = 0 Then
'Добавление новой записи
bNew = True
If vIndex(0) <> "" Then
bRedim = True
ItemNum = Ubound(vIndex)+1
Else
bRedim = False
End If
Else
bNew = False
bRedim = False
ItemNum = ItemNum-1
End If
For i = 0 To Ubound(vNames)
vArrCur = ThisDoc.GetItemValue(vNames(i))
If bRedim Then Redim Preserve vArrCur(0 To ItemNum)
If vNames(i) = "Indexes" Then
vArrCur(ItemNum) = Cstr(ItemNum+1)
Elseif vNames(i) = "RC_VacBegin" Or vNames(i) = "RC_VacEnd" Then
If bCompens Then
vArrCur(ItemNum) = "-"
Else
vArrCur(ItemNum) = Format(ThisDoc.GetItemValue(Strright(vNames(i), "_"))(0), "dd.mm.yyyy")
End If
Else
StrTmp = ThisDoc.GetItemValue(Strright(vNames(i), "_"))(0)
If StrTmp = "" Then StrTmp = "-"
vArrCur(ItemNum) = StrTmp
End If
Call ThisDoc.ReplaceItemValue(vNames(i), vArrCur)
Next i
vIndex = ThisDoc.GetItemValue("Indexes")
Call ThisDoc.ReplaceItemValue("CurItem", vIndex(ItemNum))
If VacationLen <> 0 Then
Dim OldLen As Long
If Not bNew And Isnumeric(ThisDoc.GetItemValue("VacLen0")(0)) Then
OldLen = Clng(ThisDoc.GetItemValue("VacLen0")(0))
Else
OldLen = 0
End If
VacationLen = VacationLen - OldLen
If VacationLen <> 0 Then
vArrCur = GetFieldNumArray(ThisDoc, "RC_VacPeriodUsed")
vArrCur(ItemNumTmp) = vArrCur(ItemNumTmp)+VacationLen
If vArrCur(ItemNumTmp) < 0 Then ' неверные данные ?
vArrCur(ItemNumTmp) = 0
VacationLen = VacationLen + vArrCur(ItemNumTmp) ' correct delta
End If
Call ThisDoc.ReplaceItemValue("RC_VacPeriodUsed", vArrCur)
vArrCur = GetFieldNumArray(ThisDoc, "RC_VacPeriodUnused")
vArrCur(ItemNumTmp) = vArrCur(ItemNumTmp)-VacationLen
If vArrCur(ItemNumTmp) < 0 Then vArrCur(ItemNumTmp) = 0
Call ThisDoc.ReplaceItemValue("RC_VacPeriodUnused", vArrCur)
Call ThisDoc.ReplaceItemValue("VacLen0", Clng(ThisDoc.VacLen(0)))
End If
End If
' Сортировка записей по дате
vIndex = ThisDoc.GetItemValue("Indexes")
If Ubound(vIndex) > 0 Then
vArrCur = ThisDoc.GetItemValue("RC_VacBegin")
vArrCurCopy = ThisDoc.GetItemValue("RC_VacPeriod")
'Call DoInsertSortByDate(vArrCur, vIndex)
Call DoInsertSortByDateAlt (vArrCur, vArrCurCopy, vIndex)
Call ThisDoc.ReplaceItemValue("RC_VacBegin", vArrCur)
For i = 1 To Ubound(vNames)
If vNames(i) <> "RC_VacBegin" Then
vArrCur = ThisDoc.GetItemValue(vNames(i))
vArrCurCopy = vArrCur
For k = 0 To Ubound(vIndex)
j = Clng(vIndex(k))-1
vArrCur(k) = vArrCurCopy(j)
Next k
Call ThisDoc.ReplaceItemValue(vNames(i), vArrCur)
End If
Next i
For i = 0 To Ubound(vIndex)
j = Clng(vIndex(i))-1
If j = ItemNum Then ItemNumTmp = i
vIndex(i) = Cstr(i+1)
Next i
ItemNum = ItemNumTmp
Call ThisDoc.ReplaceItemValue("Indexes", vIndex)
End If
Call Wks.CurrentDocument.Refresh
Call ThisDoc.ReplaceItemValue("RC_VacListDsp", ThisDoc.GetItemValue("RC_VacList")(ItemNum))
'errmsg :
' Msgbox Erl()
End Sub
ItemNumTmp = Arraygetindex(vArrCur, Cdat(vDatePeriod0)).
Я так понял что гемор именно с этой функцией (Arraygetindex), т.к. работает она через пень-колоду (встречал в нете). Смысл функции - взять индекс
выбранной даты в массиве, т.к. у человека который работает не первый год может быть куча отпускных периодов и нужно как-то оперировать с данными в массивах с этим индексом. Дополнительная проблема - не выявлена закономерность, т.к. на некоторых работает, на некоторых отказывается, на некоторых сначала отказывается, потом ни с того, ни с сего работает. Ломаю голову уже 3-й день. Может, переписать скрипт вставив вместо этой долбаной функции обычный цикл сравнения одного значения с каждым элементом массива. Вобщем, СОС, ай нид хэлп
<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">Sub OnAcceptChanges(Byval bNew As Boolean)
Dim StrTmp As String
Dim vNames(0 To 10) As String
Dim ItemNum As Long, i As Long, j As Long, k As Long
Dim vIndex As Variant, vArrCur As Variant, vArrCurCopy As Variant
Dim vDate0 As Variant, vDate1 As Variant
Dim vDatePeriod0 As Variant, vDatePeriod1 As Variant
Dim VacationLen As Long, ItemNumTmp As Long
Dim bRedim As Boolean, bCompens As Boolean
Dim ThisDoc As NotesDocument
Dim Wks As New NotesUIWorkspace
'On Error Goto errmsg
Call Wks.CurrentDocument.Refresh
Set ThisDoc = Wks.CurrentDocument.Document
'// Проверка полей, обязательных для заполнения
Dim str_listfields List As String
StrTmp = Lcase$(Wks.CurrentDocument.FieldGetText("VacKind"))
str_listfields("VacKind") = "Вид отпуска"
If StrTmp Like "*компенсац*" And Wks.CurrentDocument.FieldGetText("VacType")="Трудовой" Then
bCompens = True
Else
bCompens = False
str_listfields("VacBegin") = "Дата начала отпуска"
str_listfields("VacEnd") = "Дата окончания отпуска"
End If
If Lib_CheckMandatoryFields(Wks.CurrentDocument, str_listfields) = False Then Exit Sub
If ThisDoc.HideOrder(0) = "1" Then
vArrCur = ThisDoc.RC_VacType
If vArrCur(0) <> "" And Wks.CurrentDocument.FieldGetText("VacType") <> vArrCur(0) Then
Messagebox "Не допустимо предоставление и трудового и социального отпусков в одной записке.", 16, "Отпуск"
Exit Sub
End If
End If
If Not bCompens Then
vDate0 = Cdat(ThisDoc.GetItemValue("VacBegin")(0))
vDate1 = Cdat(ThisDoc.GetItemValue("VacEnd")(0))
End If
StrTmp = Wks.CurrentDocument.FieldGetText("VacLen")
If StrTmp <> "" And Not Isnumeric(StrTmp) Then
Messagebox "Неверно указана продолжительность отпуска.", 16, "Ошибка ввода"
Exit Sub
Elseif StrTmp = "" And Not bCompens Then
If Cdat(vDate1) >= Cdat(vDate0) Then
StrTmp = Cstr(vDate1 - vDate0)
Call ThisDoc.ReplaceItemValue("VacLen", StrTmp)
End If
End If
If Wks.CurrentDocument.FieldGetText("VacType") = "Трудовой" Then
If StrTmp = "" Then
Messagebox "Не задана продолжительность трудового отпуска.", 16, "Ошибка ввода"
Exit Sub
End If
i = Clng(StrTmp)
StrTmp = Wks.CurrentDocument.FieldGetText("VacPeriod")
If StrTmp = "" Or StrTmp = "-" Then
Messagebox "Не задан период трудового отпуска.", 16, "Ошибка ввода"
Exit Sub
End If
vDatePeriod0 = Cdat(Fulltrim(Strleft(StrTmp, "-")))
vDatePeriod1 = Cdat(Fulltrim(Strright(StrTmp, "-")))
If Not bCompens Then
If Cdat(vDate0)+i-1 > Cdat(vDate1) Then
Messagebox "Даты начала и окончания отпуска не согласуются с продолжительностью.", 16, "Ошибка ввода"
Exit Sub
End If
End If
VacationLen = i
vArrCur = ThisDoc.GetItemValue("RC_VacPeriodStart")
ItemNumTmp = Arraygetindex(vArrCur, Cdat(vDatePeriod0))
End If
' имена полей
vNames(0) = "Indexes"
vNames(1) = "RC_VacKind"
vNames(2) = "RC_VacType"
vNames(3) = "RC_VacPeriod"
vNames(4) = "RC_VacLen"
vNames(5) = "RC_VacBegin"
vNames(6) = "RC_VacEnd"
vNames(7) = "RC_VacOrder"
vNames(8) = "RC_VacCache"
vNames(9) = "RC_VacNotes"
vNames(10) = "RC_VacFlags"
' Определение номера текущей записи (редактирование/добавление), 0 - новая запись
StrTmp = Cstr(ThisDoc.GetItemValue("CurItem")(0))
If Not Isnumeric(StrTmp) Then ItemNum = 0 Else ItemNum = Clng(StrTmp)
If bNew Then ItemNum = 0
vIndex = ThisDoc.GetItemValue("Indexes")
If vIndex(0) <> "" And Not bCompens Then
vDatePeriod0 = ThisDoc.GetItemValue("RC_VacBegin")
vDatePeriod1 = ThisDoc.GetItemValue("RC_VacEnd")
For i = 0 To Ubound(vIndex)
If Isdate(vDatePeriod0(i)) And Isdate(vDatePeriod1(i)) Then
If (ItemNum-1) <> i And Not (Cdat(vDate1) < Cdat(vDatePeriod0(i)) Or Cdat(vDate0) > Cdat(vDatePeriod1(i))) Then
Messagebox "Заданный период пересекается с существующим: "+_
Format$(vDatePeriod0(i), "dd.mm.yyyy")+" - "+Format$(vDatePeriod1(i), "dd.mm.yyyy")+Chr$(10)+_
"( № "+Cstr(i+1)+" в списке )", 16, "Ошибка ввода"
Exit Sub
End If
End If
Next i
End If
If ItemNum = 0 Then
'Добавление новой записи
bNew = True
If vIndex(0) <> "" Then
bRedim = True
ItemNum = Ubound(vIndex)+1
Else
bRedim = False
End If
Else
bNew = False
bRedim = False
ItemNum = ItemNum-1
End If
For i = 0 To Ubound(vNames)
vArrCur = ThisDoc.GetItemValue(vNames(i))
If bRedim Then Redim Preserve vArrCur(0 To ItemNum)
If vNames(i) = "Indexes" Then
vArrCur(ItemNum) = Cstr(ItemNum+1)
Elseif vNames(i) = "RC_VacBegin" Or vNames(i) = "RC_VacEnd" Then
If bCompens Then
vArrCur(ItemNum) = "-"
Else
vArrCur(ItemNum) = Format(ThisDoc.GetItemValue(Strright(vNames(i), "_"))(0), "dd.mm.yyyy")
End If
Else
StrTmp = ThisDoc.GetItemValue(Strright(vNames(i), "_"))(0)
If StrTmp = "" Then StrTmp = "-"
vArrCur(ItemNum) = StrTmp
End If
Call ThisDoc.ReplaceItemValue(vNames(i), vArrCur)
Next i
vIndex = ThisDoc.GetItemValue("Indexes")
Call ThisDoc.ReplaceItemValue("CurItem", vIndex(ItemNum))
If VacationLen <> 0 Then
Dim OldLen As Long
If Not bNew And Isnumeric(ThisDoc.GetItemValue("VacLen0")(0)) Then
OldLen = Clng(ThisDoc.GetItemValue("VacLen0")(0))
Else
OldLen = 0
End If
VacationLen = VacationLen - OldLen
If VacationLen <> 0 Then
vArrCur = GetFieldNumArray(ThisDoc, "RC_VacPeriodUsed")
vArrCur(ItemNumTmp) = vArrCur(ItemNumTmp)+VacationLen
If vArrCur(ItemNumTmp) < 0 Then ' неверные данные ?
vArrCur(ItemNumTmp) = 0
VacationLen = VacationLen + vArrCur(ItemNumTmp) ' correct delta
End If
Call ThisDoc.ReplaceItemValue("RC_VacPeriodUsed", vArrCur)
vArrCur = GetFieldNumArray(ThisDoc, "RC_VacPeriodUnused")
vArrCur(ItemNumTmp) = vArrCur(ItemNumTmp)-VacationLen
If vArrCur(ItemNumTmp) < 0 Then vArrCur(ItemNumTmp) = 0
Call ThisDoc.ReplaceItemValue("RC_VacPeriodUnused", vArrCur)
Call ThisDoc.ReplaceItemValue("VacLen0", Clng(ThisDoc.VacLen(0)))
End If
End If
' Сортировка записей по дате
vIndex = ThisDoc.GetItemValue("Indexes")
If Ubound(vIndex) > 0 Then
vArrCur = ThisDoc.GetItemValue("RC_VacBegin")
vArrCurCopy = ThisDoc.GetItemValue("RC_VacPeriod")
'Call DoInsertSortByDate(vArrCur, vIndex)
Call DoInsertSortByDateAlt (vArrCur, vArrCurCopy, vIndex)
Call ThisDoc.ReplaceItemValue("RC_VacBegin", vArrCur)
For i = 1 To Ubound(vNames)
If vNames(i) <> "RC_VacBegin" Then
vArrCur = ThisDoc.GetItemValue(vNames(i))
vArrCurCopy = vArrCur
For k = 0 To Ubound(vIndex)
j = Clng(vIndex(k))-1
vArrCur(k) = vArrCurCopy(j)
Next k
Call ThisDoc.ReplaceItemValue(vNames(i), vArrCur)
End If
Next i
For i = 0 To Ubound(vIndex)
j = Clng(vIndex(i))-1
If j = ItemNum Then ItemNumTmp = i
vIndex(i) = Cstr(i+1)
Next i
ItemNum = ItemNumTmp
Call ThisDoc.ReplaceItemValue("Indexes", vIndex)
End If
Call Wks.CurrentDocument.Refresh
Call ThisDoc.ReplaceItemValue("RC_VacListDsp", ThisDoc.GetItemValue("RC_VacList")(ItemNum))
'errmsg :
' Msgbox Erl()
End Sub