This is an awful situation that must be fixed by ESRI. While they hide behind the philosophy that the ArcGIS Pro SDK is a DML (Data Manipulation Language) and shouldn't change any schema properties the raw truth is that most AddIns are there to produce output in the form of tables and featureclasses.
The only way to create a table is to:
1. Create the bare-bones table using the ArcToolbox tool.
2. Add each field individually using the ArcToolbox tool.
It takes ages to run (about 3 sec to add each field) and each field addition causes the whole map to redraw!
Trying to map the inputs to what the Toolbox tool accepts is a nightmare.
The code below works but I'm not proud of it.
public static async Task<string> CreateFeatureClass(string sFGDB, string sFCName,
string sGeomType, SpatialReference pProjection)
{
// Create a Feature Class in sFGDB. This must be done by calling the Create FeatureClass GP tool
// and then calling the Add Field GP Tool mulitple times. Geez!
// Create featureclass requires:
// ******** CREATE ********
// Workspace
// FC Name
// Geometry Type; E.G. "Polygon"
// Template FC (Can be null)
// Has M (Yes/No)
// Has Z (Yes/No)
// Projection SpatialReference object
// Alias Name
//
string sError = "";
string sToolPath;
string sTablePath = sFGDB + "\\" + sFCName;
string sProjectionString = "";
try
{
sToolPath = "management.CreateFeatureClass";
sProjectionString = pProjection.Wkt;
var args = Geoprocessing.MakeValueArray(sFGDB, sFCName, sGeomType, null, "No", "No",
sProjectionString);
IGPResult result = await Geoprocessing.ExecuteToolAsync(sToolPath, args, null, null, null,
GPExecuteToolFlags.None);
if (result.IsFailed == true)
{
StringBuilder sErr = new StringBuilder();
string sSep = "";
foreach (IGPMessage pErr in result.ErrorMessages)
{
sErr.Append(sSep + pErr.Text);
sSep = "\r\n";
}
sError = "Error: Create Table Failed\r\n" + sErr.ToString();
return sError;
}
return sError;
}
catch (Exception ex)
{
System.Diagnostics.StackTrace pStack = new System.Diagnostics.StackTrace(ex, true);
System.Diagnostics.StackFrame pFrame = pStack.GetFrame(pStack.FrameCount - 1);
int iLineNo = pFrame.GetFileLineNumber();
sError = "Error: CreateFeatureClass; Line: " + iLineNo + "\r\n" + ex.Message;
return sError;
}
}
public static async Task<string> addFields(string sGDB, string sFCorTable,
List<clsConfig.tFieldDetails> sFields)
{
string sError = "";
string sToolPath;
string sTablePath = sGDB + "\\" + sFCorTable;
string sFieldName;
string sFieldType;
string sFieldLength;
try
{
await ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(async () =>
{
using (Geodatabase geodatabase = new Geodatabase(new FileGeodatabaseConnectionPath(new Uri(sGDB))))
using (FeatureClass pFC = geodatabase.OpenDataset<FeatureClass>(sFCorTable))
{
// Add the fields
sToolPath = "management.AddField";
// ******* FIELDS ********
// Input Table or FC as FeatureClass or Table
// Field Name
// Field Type "TEXT", "LONG", "DOUBLE" etc
// Field Length (Text fields only)
// Precision (null for FGDB)
// Field Alias
int iFldNo = 0;
foreach (clsConfig.tFieldDetails pFld in sFields)
{
sFieldName = pFld.sFldName;
sFieldType = pFld.sFldType;
var args = Geoprocessing.MakeValueArray(pFC, sFieldName, "DOUBLE", 6);
if (sFieldType == "TEXT")
{
args = Geoprocessing.MakeValueArray(pFC, sFieldName, "TEXT", 30);
}
IGPResult result = await Geoprocessing.ExecuteToolAsync(sToolPath, args, null);
if (result.IsFailed == true)
{
sError = "addFields: Add field failed\r\n" + sTablePath + "\r\n" + sFieldName + "\r" +
"Field No " + iFldNo.ToString() + "\r\n";
StringBuilder sErr = new StringBuilder();
string sSep = "";
foreach (IGPMessage pEr in result.ErrorMessages)
{
sErr.Append(sSep + pEr.ErrorCode + " " + pEr.Text);
sSep = "\r\n";
}
sError += sErr.ToString();
break;
}
iFldNo++;
}
}
});
return sError;
}
catch (Exception ex)
{
System.Diagnostics.StackTrace pStack = new System.Diagnostics.StackTrace(ex, true);
System.Diagnostics.StackFrame pFrame = pStack.GetFrame(pStack.FrameCount - 1);
int iLineNo = pFrame.GetFileLineNumber();
sError = "Error: addFields; Line: " + iLineNo + "\r\n" + ex.Message;
return sError;
}
}