Revision History – Subscript Out of Range Error

pts.
Tags:
Lotus Domino
Hi, I have some script that updates 4 revision history fields. It works fine when the revision dates are to be in descending order but I am having problems changing it so that the results are in ascending order.. The code is as follows: Sub CL_RevHistory(doc As NotesDocument) Dim index As Integer, num As Integer Dim editors As Variant, actions As Variant, targetdates As Variant, actualdates As Variant editors = doc.ActionedBy If (editors(0) = "") Then doc.ActionedBy = CL_CurrentUser doc.Action = Rev doc.TargetDate = TargetDte doc.ActualDate = Now Exit Sub End If actions = doc.Action targetdates = doc.TargetDate actualdates = doc.ActualDate num = Ubound(editors) + 1 If (num < 20) Then Redim Preserve editors(num) Redim Preserve actions(num) Redim Preserve targetdates(num) Redim Preserve actualdates(num) num = num + 1 End If For index = num - 1 To 1 Step -1 editors(index) = editors(index - 1) actions(index) = actions(index - 1) targetdates(index) = targetdates(index - 1) actualdates(index) = actualdates(index - 1) Next editors(0) = CL_CurrentUser actions(0) = Rev targetdates(0) = TargetDte actualdates(0) = Now doc.ActionedBy = editors doc.Action = Actions doc.TargetDate = targetdates doc.ActualDate = actualdates End Sub I have tried replacing the For statement with various things, such as the below: For index = 0 To num editors(index) = editors(index + 1) actions(index) = actions(index + 1) targetdates(index) = targetdates(index + 1) actualdates(index) = actualdat(index + 1) Next Or using ubound but everything I have tried gets a "Subscript out of range" error.. Any help would be greatly appreciated. Kate

Answer Wiki

Thanks. We'll let you know when a new response is added.

What happens when you step through the code with the debugger?

Discuss This Question: 15  Replies

 
There was an error processing your information. Please try again later.
Thanks. We'll let you know when a new response is added.
Send me notifications when members answer or reply to this question.

REGISTER or login:

Forgot Password?
By submitting you agree to receive email from TechTarget and its partners. If you reside outside of the United States, you consent to having your personal data transferred to and processed in the United States. Privacy
  • CharlesJC
    Kate, Arrays are zero-based (e.g. Dim lArr(5) as string = Dim lArr(0 to 4) as string). So, "num = num +1" is your problem, because you incremented num beyond Ubound(editors). This makes your desceding for loop index out of range when index = num - 1 (still one greater than Ubound(editors). In you ascending for loop, when index = num it is then greater that Ubound(editors). If you remove the "num = num + 1" then the descending for loop should work. You will need to change your ascending for loop to start like "for index = 0 to num - 1" then you won't be out of the subscript range when you get to the last element. You can also set up your array transversing for loops to use the upper (or lower) bound of the array to avoid this problem in the future. (e.g. "for index = Ubound(editors) -1 to 1 Step - 1 " or "for index = 0 to Ubound(editors) - 2". Note: In both cases I am stoping one element short or traversing all elements in the array, as per your specific condition of inserting values in the first element of the arrays. I hope this helps. Charles
    0 pointsBadges:
    report
  • Katyep
    It does the For statement once then errors on editors(index) = editors(index + 1) All of the variables - editors, actions, targetdates, actualdates - are null.
    0 pointsBadges:
    report
  • Stiletto
    First, let's pick whether you're going to use the ascending or descending, or this will be more difficult then necessary. From your response, it sounds like you want to use the ascending. a) It's not the immediate problem, but you will need to change n to n-1 in the For statement. b) Are you saying the body of the loop never even executes once (dies on first statement inside loop first time)? If so, when you say the variables are null, do you mean they aren't even arrays? If so, there's the problem. You can't access an element of an array if you don't have an array in the first place. If that's the case, your problem isn't the loop; it's the assignments further up in the code. c) Another possibility is that Option Base is set to 1, instead of 0.
    3,420 pointsBadges:
    report
  • Brooklynegg
    Trying to manage an index in this way is quite difficult and makes a lot more work than necessary. Assign the field value to a variant, which will become an array, then append the new value to the array. Finally, assign the array back to the field. Example: 'Dim stuff you need below. Don't have to Dim VarCustAcctNo. Might not work if you do. Dim AddedValue as string VarCustAcctNo =doc.CustAcctNo AddedValue = "New TopList Value" doc.CustAcctNo =Fulltrim(Arrayappend(AddedValue,VarCustAcctNo))
    3,845 pointsBadges:
    report
  • Katyep
    Thank you all for your posts... I have made changes according to your suggestions but I STILL can't get this working: Sub CL_RevHistory(doc As NotesDocument) Dim index As Integer, num As Integer Dim editors As Variant, actions As Variant, targetdates As Variant, actualdates As Variant editors = doc.ActionedBy If (editors(0) = "") Then doc.ActionedBy = CL_CurrentUser doc.Action = Rev doc.TargetDate = TargetDte doc.ActualDate = Now Exit Sub End If actions = doc.Action targetdates = doc.TargetDate actualdates = doc.ActualDate num = Ubound(editors) + 1 If (num
    0 pointsBadges:
    report
  • CharlesJC
    Kate, What do you get with this code (I made a couple of changes)? Sub CL_RevHistory(doc As NotesDocument) Dim index As Integer, num As Integer Dim editors As Variant, actions As Variant, targetdates As Variant, actualdates As Variant editors = doc.ActionedBy If (editors(0) = "") Then doc.ActionedBy = CL_CurrentUser doc.Action = Rev doc.TargetDate = TargetDte doc.ActualDate = Now Exit Sub End If actions = doc.Action targetdates = doc.TargetDate actualdates = doc.ActualDate num = Ubound(editors) + 1 Redim Preserve editors(num) Redim Preserve actions(num) Redim Preserve targetdates(num) Redim Preserve actualdates(num) For index = num - 1 To 1 Step - 1 'Start at the end and go backwards, so you don't overwrite your data. editors(index - 1) = editors(index) actions(index - 1) = actions(index) targetdates(index - 1) = targetdates(index) actualdates(index - 1) = actualdates(index) Next editors(0) = CL_CurrentUser actions(0) = Rev targetdates(0) = TargetDte actualdates(0) = Now doc.ActionedBy = editors doc.Action = Actions doc.TargetDate = targetdates doc.ActualDate = actualdates End Sub Let me know how this works.
    0 pointsBadges:
    report
  • Katyep
    Charles Still the same I'm afraid. It's been suggested that I try arrayappend instead so I'm going to see where I get with that. Many thanks Kate
    0 pointsBadges:
    report
  • Stiletto
    First, I don't think the code CharlesJC just provided will work; I think it will set all of the array elements to be the same. Now, no offense, but what you're describing doesn't make sense. The For statement itself can't possibly be changing the values of your variables (unless you've got some major corruption somewhere). Either the variables are changing before the For or somewhere inside the loop. Remove the num=num+1 line inside the If statement. There's no need for it and it's just confusing the issue of the loop boundaries. Then step through the code in the debugger noting the variable values at each step. If it doesn't work, post the variable values from just before it goes bad and the same values as soon as it goes bad.
    3,420 pointsBadges:
    report
  • Stiletto
    >...the dates remain the same. Are you saying they don't get an extra element added on at the ReDim? If so, comment out the date parts of the loop to narrow down the problem. >In the For loop At what POINT in the For loop? What version of the For loop - ascending, descending, upper limit, lower limit? What's the value of num at the time? What about index? Are you still getting an error, or just not the results you want?
    3,420 pointsBadges:
    report
  • Katyep
    Yes, at the redim the extra elements are not being added on. If I use the following For loop: For index = num - 1 To 1 Step -1 editors(index) = editors(index - 1) actions(index) = actions(index - 1) targetdates(index) = targetdates(index - 1) actualdates(index) = actualdates(index - 1) Next it works fine but the elements are descending, I need them to be ASCENDING so have tried For index = 0 To num -1 editors(index) = editors(index + 1) actions(index) = actions(index + 1) targetdates(index) = targetdates(index + 1) actualdates(index) = actualdates(index + 1) Next It is not erroring, just the original elements are not preserved so the field values only contain the new revision and not previous ones. At the For loop Index = 0 Num = 1
    0 pointsBadges:
    report
  • Stiletto
    I think you've got a conceptual problem here. The ReDim will basically add an extra element to the end (we'll call it the top) of the array. Your first loop (the one you say gives results in descending order) should be For index = num To 1 Step -1. Once that's corrected, it will move each element up one place, leaving element 0 open to be overwritten. But, since you say that's not the order you want, then you don't need a loop at all. The ReDim adds the extra element to the top. You can just overwrite it. Or, you could blow off the ReDim altogether and just use ArrayAppend. The results you're getting are to be expected. You're moving the elements DOWN by one, which results in throwing away the first element. The date variables are a separate issue. Try actualdates = doc.GetItemValueDateTimeArray("ActualDate") or actualdates = doc.ActualDate.Values to see if either resolves the failing ReDim.
    3,420 pointsBadges:
    report
  • Deadleaves
    Listen to BrooklynEgg, he's on the right track. Never (in any language) try to rebuild an array only using the array itself as your work area. Too hard and frought with problems. Create a new array big enough to hold your new results then build the new array how ever you want. When new array is complete, replace the original fields with this array. Something like below: 'Depending on the data type of your fields might 'want to declare arrays something other than variant Dim newFld1() As Variant Dim newFld2() As Variant Dim newFld3() As Variant oldFld1 = doc.Fld1 oldFld2 = doc.Fld2 oldFld3 = doc.Fld3 'Number of elements in temp array = number of elements in 'original fields + 1 '(assuming all fields have same number of elements) i = Ubound(oldFld1) If i = 0 And oldFld1(0) = "" Then 'This is for first time when nothing in doc.Fld1 yet Else i = i + 1 End If 'Create temp arrays with new size Redim newFld1(i) Redim newFld2(i) Redim newFld3(i) 'Load temp arrays starting with new value at top For x = 0 To i If x = 0 newFld1(x) = CL_CurrentUser newFld2(x) = Rev newFld3(x) = TargetDte Else newFld1(x) = oldFld1(x - 1) newFld2(x) = oldFld2(x - 1) newFld3(x) = oldFld3(x - 1) End If Next 'Replace document fields with new array doc.Fld1 = newFld1 doc.Fld2 = newFld2 doc.Fld3 = newFld3 See, doesn't that look a lot easier?
    0 pointsBadges:
    report
  • Brooklynegg
    Thanks, Deadleaves. This is a quite compact version that ignores the ubound and simply pre-pends the contents of Action to ActionHistory. You'd want to add a bunch more control around when and why you would append the value, such as, don't append if doc.Action(0) = Doc.ActionHistory(0). Dim doc As NotesDocument Set doc = source.document varAction = doc.Action varActionHistory =doc.ActionHistory doc.ActionHistory =Fulltrim(Arrayappend(varAction ,varActionHistory)) Call doc.Save(True, False)
    3,845 pointsBadges:
    report
  • Katyep
    Thanks to you all for your advice and suggestions, they've been a lot of help for this and other problems I've had. In the end I took Brooklyn's advice and used arrayappend which was so much easier than my original code! Thanks again everyone.
    0 pointsBadges:
    report
  • Lisainfo
    Hi, Kate, Recording history would be a very simple action. I think your original attempt would be to limit the history entries to 20. You may try using formula like this in each field you would like record the changed history : e.g Field Name : ActionedBy Type : Text ; Computed ; Allow Multiple Values (please set up the display format as you like) Value : @if(@IsDocBeingSaved; @If(ActionedBy=""; CL_CurrentUser; @Subset(CL_CurrentUser:ActionedBy;20)); ActionedBy); In this case, the field only changes its value when the doc is saved and the value is updated by adding the CL_CurrentUser to the ActionedBy list(you may change the order by adding CL_CurrentUser to the back of ActionedBy) and the limit of the list is 20. Hope this help. Lisa
    0 pointsBadges:
    report

Forgot Password

No problem! Submit your e-mail address below. We'll send you an e-mail containing your password.

Your password has been sent to:

To follow this tag...

There was an error processing your information. Please try again later.

REGISTER or login:

Forgot Password?
By submitting you agree to receive email from TechTarget and its partners. If you reside outside of the United States, you consent to having your personal data transferred to and processed in the United States. Privacy

Thanks! We'll email you when relevant content is added and updated.

Following