This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Method GetNextID for DialogNextID not working anymore?

Hi people,

I've recently tried to call the method "GetNextID" on a DialogNextID object using a script. It seems that calling this method does not affect the loaded DialogNextID object. I was wondering if anyone else ran into this problem in 8.0.1.

My script below tries to set a DialogNextID to a specific NextNumber throught the object layer (I am ware the same can be achieved through SQL, but why should the callmethod not work in this instance?)

Has anyone else tried to use the NextID method already? Thanks for your feedback!

Public Sub CCC_Set_StartingCount_GlobalID(ByVal globalIDCount As Integer, Optional ByVal resetCounter As Boolean = False)

' Get or create GlobalID Counter

Dim f As ISqlFormatter = Session.SqlFormatter

Dim globalID As IEntity = Nothing

If Not Session.Source.TryGet(Query.From("DialogNextID") _

.Where(f.Comparison("Ident_DialogNextID", "GlobalID", ValType.String)) _

.GetQuery, globalID) _

Then

globalID = Session.Source.CreateNew("DialogNextID")

globalID.PutValue("Ident_DialogNextID", "GlobalID")

globalID.Save(Session)

End If

If Not resetCounter Then

' Set GlobalID counter to appropriate count

If CInt(globalID.GetValue("NextNumber")) < globalIDCount Then

While Not CInt(globalID.GetValue("NextNumber")) = globalIDCount

Debug.WriteLine(CStr(globalID.GetValue("NextNumber")))

End While

End If

Else

' Reset GlobalID Counter

CCC_Run_SQLWithResult(String.Format("UPDATE DialogNextID SET NextNumber = 0 WHERE {0}",

f.UidComparison("UID_DialogNextID", globalID.GetValue("UID_DialogNextID"))))

End If

End Sub

Parents
  • Resetting DialogNextID.NextNumber using the object layer and GetNextID is a bad idea and should not be considered. Please remember that any execution of GetNextID issues a write to the database. So when you are iterating the counter by adding 1 at a time, this puts an unnecessary load onto the database server. 

    If you need to constantly change your NextNumber then it is better to delete the entry in DialogNextID and create a fresh one correctly initialized with your new number.

    In regards to your claim that calling GetNextID does not change the already loaded object, this is true because it wouldn't make sense to do so in a multi-user environment. At the time the local entity would have been updated, another user (or thread, job service, anything) could have called the same method and your local entity would have been invalid again.

    By the way, the intended use of DialogNextID is not to read the value from NextNumber but to use the function GetNextID to fetch the next number directly and immediately. A requirement to be able to make that function call, is to load the Entity with the EntityLoadType.Interactive (The same requirement applies to a method call of GetNextID).

    Sample: Fetch the next value from DialogNextID

    Dim globalID As IEntity = Nothing
    Dim nextID As Integer
    
    If Session.Source.TryGet(Query.From("DialogNextID"). _
                         Where(f.Comparison("Ident_DialogNextID", "GlobalID", ValType.String)). _
                         GetQuery, EntityLoadType.Interactive, globalID) Then
        nextID = CInt(globalID.CallFunction("GetNextID"))
    End If
    

    You can subsequently call the function and the value will always return the next valid value, regardless what the current value of the NextNumber property.

    HtH

  • Hi Markus,

    can you think of a reason why the following code works as intended when running the script using the debugger in Visual Studio but not when running the code using the script tester in designer or calling the function through a template?

    When running the code through designer, the script runs into a timeout if the DialogNextID Object is not loaded in the database. Once the object is loaded, it will call a next ID exactly once no matter how many times the script is run. Once one raises the count of the DialogNextID manually though object browser, the script will raise the count of the object exactly once. When calling the function using a template, the timeout exception is thrown again.

    Directly pasting the logic as a template seems to solve the issue but I can't understand why.

    Public Function CCC_New_GlobalID() As String
        ' Get or create GlobalID Counter
        Dim f As ISqlFormatter = Session.SqlFormatter
        Dim globalID As IEntity = Nothing
        If Not Session.Source.TryGet(Query.From("DialogNextID") _
                                      .Where(f.Comparison("Ident_DialogNextID", "GlobalID", ValType.String)) _
                                      .GetQuery, EntityLoadType.Interactive, globalID) _
        Then
            globalID = Session.Source.CreateNew("DialogNextID", EntityCreationType.Interactive)
            globalID.PutValue("Ident_DialogNextID", "GlobalID")
            globalID.Save(Session)
            Dim void = CCC_Run_SQLWithResult(String.Format("UPDATE DialogNextID SET NextNumber = 5023 WHERE UID_DialogNextID = '{0}'",
                                                                            globalID.Reload(Session).GetValue("UID_DialogNextID").String))
        End If
    
        Using t As New Transaction(Session)
            globalID.CallMethod("GetNextID")
            t.Commit()
        End Using
        Dim nextID As Integer = globalID.Reload(Session).GetValue("NextNumber")
    
        ' Convert GlobalID counter to Hexadecimal and add a hyphen for every fourth character 
        Dim result As String = String.Join("-", Regex.Split(nextID.ToString("X"), "(.{4})") _
                                            .Where(Function(x) x.Length > 0))
    
        Return result
    End Function

  • If you test this in Designer you need to activate the flag to use the main database and not the local copy inside of the Designer. Did you do that?

    Secondly, you should use the Transaction in combination with the CallMethod. Just use the CallFunction method as instructed should be sufficient.

  • Hi Markus,


    I've flagged the script tester to use the main database connection and removed the transaction statement, the results are the same. It wouldn't explain why I can't call the function from a template anyhow.

  • I used the following script and it worked in the Script Tester in Designer. The result value increments by one each time I ran the script.

    Public Function CCC_New_GlobalID() As String
        ' Get or create GlobalID Counter
        Dim f As ISqlFormatter = Session.SqlFormatter
        Dim globalID As IEntity = Nothing
        If Not Session.Source.TryGet(Query.From("DialogNextID") _
                                      .Where(f.Comparison("Ident_DialogNextID", "GlobalID", ValType.String)) _
                                      .GetQuery, EntityLoadType.Interactive, globalID) _
        Then
            globalID = Session.Source.CreateNew("DialogNextID",EntityCreationType.Interactive)
            globalID.PutValue("Ident_DialogNextID", "GlobalID")
    		globalID.Save(Session)
        End If
    
        
    
    	Dim nextID As Integer = CInt(globalID.CallFunction("GetNextID"))
    
        ' Convert GlobalID counter to Hexadecimal and add a hyphen for every fourth character 
        Dim result As String = String.Join("-", Regex.Split(nextID.ToString("X"), "(.{4})") _
                                            .Where(Function(x) x.Length > 0))
    
        Return result
    End Function

    How did you test the script in a template? My script works even in a template as long as the object is loaded as interactive.

  • Hi Markus,

    I've copy pasted and tested your script using the script tester in designer at two different customers using 8.0.1. In both cases, the NextNumber cannot be raised. 

    I've used the script in a template as follows (as an overwriting template). As mentioned before the NextNumber is not raised.

    If Not $[ISLoaded]:Bool$ Then Value = CCC_New_GloablID()

    If one however does not call the function but paste only the logic of the script directly into the template then everything works as designed.

    I've had a chance to speak to René Obermüller, he says that the API for DialogNextID has changed since Version 6. He hasn't had a chance to look deeper into the issue though.

  • Sorry for being picky but where and how did you test the template?

  • That's quite alright. I extended the schema of the Person Table with a String Field "CCC_GlobalID" and pasted the logic of the function as an overwriting template of CCC_GlobalID field. After saving, compiling and starting a new session for Manager, I created a new Employee and checked if it had a new global ID or not. The template of CCC_GlobalID looks like this.

    If Not $[IsLoaded]:Bool$ Then
        Dim f As ISqlFormatter = Session.SqlFormatter
        Dim globalID As IEntity = Nothing
        If Not Session.Source.TryGet(Query.From("DialogNextID") _
                                    .Where(f.Comparison("Ident_DialogNextID", "GlobalID", ValType.String)) _
                                    .GetQuery, EntityLoadType.Interactive, globalID) _
        Then
            globalID = Session.Source.CreateNew("DialogNextID", EntityCreationType.Interactive)
            globalID.PutValue("Ident_DialogNextID", "GlobalID")
            globalID.Save(session)
        End If
        
        Dim nextID As Integer = CInt(globalID.CallFunction("GetNextID"))
        
        Value = String.Join("-", Regex.Split(nextID.ToString("X"), "(.{4})") _
                            .Where(Function(x) x.Length > 0))
    End If

    So one can invoke the "GetNextID" method using a template, but it would seem that the same method cannot be called through a script.

  • I tried this again and it works in my environment in the Designer (Script Tester) and in the Object Browser with the short form of the template that calls my script sample.

    Two things that you need to consider

    • The function call GetNextID will return the current value from DialogNextID.NextNumber and update its value in the database afterward. Please keep that in mind as a single test run could fool you into thinking that the value isn't incrementing.
    • In the Script Tester, you have to turn the use of transactions off. Another thing that could fool you into thinking that the value isn't incrementing.

    Anyways, if it still not working in your case you do have a working sample by integrating the code into the template. And be assured that this is working in the next service pack of 8.0 (my environments have newer hotfix builds running than 8.0.1 so if it is running in my environments but not in your 8.0.1 it will be running in 8.0.2 for sure).

  • Thanks again for taking your time to test it and for your thoughful insights. I look forward to testing this issue in 8.0.2

Reply Children
No Data