GeodatabaseUI.ICalculatorUI2 no longer works in ArcMap 10.1

1012
5
Jump to solution
06-23-2014 08:22 AM
RobertMaddox
New Contributor III
I have an addin that has been ported from ArcMap 9.3 to 10.1 and this code worked perfectly in 9.3 but for some reason won't work at all in 10.1:

ICalculatorUI calc = new CalculatorUI();
calc.Table = MyTable;
calc.Field = "MyField";
calc.DoModal(ArcMap.Application.hWnd);

The actual code is a little more complicated than that, but I've tried it with this simplified version and it still doesn't work.

What happens is the calculator dialog pops up just fine and I can enter a value to set the field to, but when I hit the OK button, the dialog closes without error, but nothing has been updated.

I've opened the table that I'm editing using ArcMap's regular ui and launched the Field Calculator on the same field and can confirm that it looks exactly like what I see when I use this bit of code on my own form. There are only three differences:


  • Prior to the dialog displaying, there's a warning dialog that pops up telling me that I'm not in an editing session and the changes can't be undone.

  • After the OK button is pressed, a progress dialog shows briefly while the rows are being updated.

  • The rows are actually updated.

So everything that is displayed on the dialog itself is identical, including the name of the field and the list of other fields in the table.

In ArcMap 9.3, the `ICalculatorUI` would take over everything as soon as `DoModal` was called. It annoyingly didn't even provide feedback programmatically to signify if the user canceled the dialog or [if/how many] rows were updated. Very black box and it sucked, but at least it worked!

I've not been able to find any help on this anywhere, especially not on ESRI's pathetic documentation, which appears to be copied and pasted from their 9.x documentation. I've also posted this question on StackOverflow, but haven't gotten any responses there either and it's been almost two weeks...

I have people waiting on this, so any help would be greatly appreciated. Thanks.
0 Kudos
1 Solution

Accepted Solutions
RobertMaddox
New Contributor III

So for anyone interested, I am now using ICalculate to execute the expressions that were provided by the user. Of course this has several drawbacks, one of them being that if the users selects to use Python, it will fail. But there wasn't a better choice. At least I was able to figure out how to limit it to only updating the selected records (have to use ISelectionSet2.Update to get an update cursor).

I just hope that ESRI doesn't just decide to secretly make it go back to the way it was at some point in the future and then the expressions get processed twice...

View solution in original post

0 Kudos
5 Replies
DuncanHornby
MVP Notable Contributor
Robert,

I agree I think this object and it's interface is broken. I tried to get it working in VBA and it was having none of it. My only suggestion is to use the GeoProcessing tool Calculate Field if you want to be able to alter the expression on the fly? I assume you want to do it that way as you are calling up the UI?

Duncan
RobertMaddox
New Contributor III
Thanks Duncan for your reply! Glad to see that I'm not the only one having problems with it. As for your suggestion, are you talking about calling a geoprocessor (or ICalculator) from code? The problem with that is that the calculations are user provided. I could create a user interface that would allow the user to specify the calculations to use, but then I would have to deal with validation issues and the like, which I would really like to avoid since it would likely drive this already overdue migration project out of scope and over budget. 😕

Another issue I found when trying to use the ICalculator interface was that there's no way to cause it to only update the selected records because you have to provide an ICursor, which means I could use an IQueryFilter to filter it out, but an ISelectionSet doesn't really translate into a query very well since it only has the OIDs of the selected records.

Thanks again for your reply. I'd appreciate any other thoughts you might have. 🙂
0 Kudos
DuncanHornby
MVP Notable Contributor
Robert,

Your problem got me thinking about how to open up a GeoProcessing tool and see its UI. I worked out the following code this is a viable alternative, written in VBA but I'm sure you can edit it?

Public Sub OpenCalculateTool()


    ' Hook into Toolbox and get the tool
    Dim pUID As New UID
    pUID = "esriGeoprocessingUI.ArcToolboxExtension"
    Dim pArcToolboxExtension As IArcToolboxExtension
    Set pArcToolboxExtension = Application.FindExtensionByCLSID(pUID)
    Dim pArcToolbox As IArcToolbox
    Set pArcToolbox = pArcToolboxExtension.ArcToolbox
    Dim pGPTool As IGPTool
    Set pGPTool = pArcToolbox.GetToolbyNameString("CalculateField")
      
    ' Create messages, required by Invoke method
    Dim msgs As IGPMessages
    Set msgs = New GPMessages


    ' Get existing parameter structure
    Dim pArray As IArray
    Set pArray = pGPTool.ParameterInfo
    
    ' Declare Parameter interfaces
    Dim pGPParameter As IGPParameter
    Dim pGPDataType As IGPDataType
    Dim pGPParameterEdit As IGPParameterEdit
    
    ' Set the parameters of the tool
    Set pGPParameter = pArray.Element(0)
    Set pGPParameterEdit = pGPParameter
    Set pGPDataType = pGPParameter.DataType
    Set pGPParameterEdit.Value = pGPDataType.CreateValue("a") ' Featurelayer name
    Set pGPParameter = pArray.Element(1)
    Set pGPParameterEdit = pGPParameter
    Set pGPDataType = pGPParameter.DataType
    Set pGPParameterEdit.Value = pGPDataType.CreateValue("xx") ' Field
    Set pGPParameter = pArray.Element(3)
    Set pGPParameterEdit = pGPParameter
    Set pGPDataType = pGPParameter.DataType
    Set pGPParameterEdit.Value = pGPDataType.CreateValue("VB")


    ' Open the tool
    Dim pGPToolCommandHelper As IGPToolCommandHelper2
    Set pGPToolCommandHelper = New GPToolCommandHelper
    pGPToolCommandHelper.SetTool pGPTool
    pGPToolCommandHelper.InvokeModal 0, pArray, True, msgs
End Sub
0 Kudos
RobertMaddox
New Contributor III
Well, I just looked at the Calculate Field tool in ArcMap and it does provide a decent way of entering the calculation once the table and field have been selected. However, I don't think it'll work in the flow that I need to have. The place where I was using ICalculatorUI is in a customized view of the table using a GridView and it depends on the field being locked down so that it can scan through the table when the calculation is done and update the values for that column.

One of the big annoyances in the original setup with ICalculatorUI was that there was no indication of whether or not anything was actually done, so even if the user canceled the dialog, it still had to walk the table comparing the values in the selected field with what was in the GridView. If I were to replace that with the Calculate Field tool, it would mean that the user could easily chose a different field (or even a different table) to change and I would have no way of knowing it. So then I would have to scan the entire table for changes on any of the fields. :eek:

So for that reason, and others, I just don't think it'll work out to use toolbox tools to do what I need. Thanks for your suggestion and working out the code though. 😉
0 Kudos
RobertMaddox
New Contributor III

So for anyone interested, I am now using ICalculate to execute the expressions that were provided by the user. Of course this has several drawbacks, one of them being that if the users selects to use Python, it will fail. But there wasn't a better choice. At least I was able to figure out how to limit it to only updating the selected records (have to use ISelectionSet2.Update to get an update cursor).

I just hope that ESRI doesn't just decide to secretly make it go back to the way it was at some point in the future and then the expressions get processed twice...

0 Kudos