Ok sleep helped. I’ve got it working. The gist of the problem is that when you manually create a row, it doesn’t initialize (things like fields that cant be null,company, sysrow etc).
You can manually create rows but you have to populate EVERYTHING - usually when using GetaNewUD39 it populates most of the mundane. BTW - You can use the typed fields of the (row) - I just haven’t went back to reformat it. I.E. row.Company = “CP”;
for (int record = 0; record < howmany; record++)
{
var row = a.UD39Data.UD39.NewUD39Row();
row.BeginEdit();
//init the damn thing...... You better do all of this OR ELSE
for (int x = 1; x <= 20; x++)
{
row["CheckBox" + x.ToString("d2")] = false;
row["Number" + x.ToString("d2")] = 0;
row["ShortChar" + x.ToString("d2")] = "";
if(x<11) row["Character" + x.ToString("d2")] = "";
row["Date" + x.ToString("d2")] = DBNull.Value;
}
//other required fields you MUST fill
row["Company"] = company;
row["RowMod"] = "A";
row["BitFlag"] = false;
row["GlobalUD39"] = false;
row["GlobalLock"] = false;
row["SysRowID"] = new Guid();
row["SysRevID"] = 0;
//the rest of your actual data here
row.EndEdit();
a.UD39Data.UD39.AddUD39Row(row);
}
a.Update();
```
What do you figure the best way to get and modify a handful of records at once is. I’ve been chugging along one at a time with GetByID. I am thinking I could use the same method above in creating new rows in the UDdata ds based on results from a GetRows with a whereclause. I expect I could just pipe the entire ds result of GetRows, creating a new row in the UDdata ds. From there modification should be straight forward with a lonely Update() at the end.
Thoughts? Suggestions?
Also, btw, if I haven’t mentioned it lately, I am so thankful that an expert such as yourself takes so much time to give us your wisdom and opinions here. It really makes us feel loved. That goes for the rest of you Epicor knuckleheads as well
I’m such a bozo… ImportRow() for the win. Solves all those problems
Singleton.a.ClearData();
SearchOptions opts = new SearchOptions(SearchMode.AutoSearch);
opts.NamedSearch.WhereClauses.Add("UD39","Key1 = '996'");
bool more = false;
UD39DataSet ds = (UD39DataSet)Singleton.a.GetRows(opts, out more);
foreach (UD39Row row in ds.UD39.Rows)
{
//TEST CHANGING SOME DATA
row.BeginEdit(); //we'll modify the 'valid' row
row.Number01 = 61;
row.EndEdit();
Singleton.a.UD39Data.UD39.ImportRow(row); //now all your base are belong to us
}
Singleton.a.Update();
And to add to the Bozo-ery, I think you were suggesting this (which would probably work as well)
@Chris_Conn - I found this thread because I am attempting a similar thing. Trying to get legacy data, parse it, and shove it into a UD table so that we can reference it inside Epicor. So I am trying to add many rows at once. Your threads are always entertaining… as a way of laughing at the situation:
I just spent the better part of a day trying to chase down an error I was getting about a key already existing so it could not add the row… I could not figure it out. But eventually, after many failed attempts, I eventually realized that it was failing on the 36th row of data I was trying to add. So I inspected that row, and lo-and-behold, it was the key in my dictionary that it was yelling at me about - not the key in my UD table!!
I was making the assumption that the field I was parsing would have the same layout in all rows - but I came across some rows that did not. So my parsing statement was failing horribly.
In all seriousness, I do have a pertinent question. So in my exercise of futility, I am trying to take all this data (from our Orders tables) and push in pertinent information to our UD table. I am checking first to see if the data is there (in my live environment, there will be existing data and I don’t want to duplicate/overwrite what’s there). If it’s not there, I use a GetaNewUD38 and I have that ironed out and working. If it finds rows, I am trying to update the existing row… Below is what I’ve got. Help. I get no errors, but I can’t get anything to update in my UD table.
foreach (var eachRelease in getOrderRel)
{
int i = 0;
int releaseNum = eachRelease.OrderRelNum;
Decimal releaseQty = eachRelease.Qty;
var checkForExisting = (from t in Db.UD38
where t.Key1 == eachOrderLine.OrderNum.ToString()
&& t.Key2 == eachOrderLine.OrderLine.ToString()
&& t.Key3 == releaseNum.ToString()
select t);
if (checkForExisting.Count() == 0)
{
//------ CREATE A NEW LINE IN UD38 FOR EACH QUANTITY IN THE ORDER (EACH SERIAL NUMBER NEEDS ITS OWN LINE)-------
while (i < Convert.ToInt32(releaseQty))
{
try
{
boUD38.GetaNewUD38(ref dsUD38);
dsUD38.UD38[0].Key1 = eachOrderLine.OrderNum.ToString();
dsUD38.UD38[0].Key2 = eachOrderLine.OrderLine.ToString();
dsUD38.UD38[0].Key3 = releaseNum.ToString();
dsUD38.UD38[0].Key5 = i.ToString();
boUD38.Update(ref dsUD38);
}
catch (Exception ex)
{
}
i++;
} // end while
} // end if
//------------IF LINE ALREADY EXISTS, UPDATE EXISTING LINE ----------------------------------------------
else
{
foreach (var eachRow in checkForExisting)
{
string jobNum = eachRow.Key4;
string serialNum = eachRow.Key5;
try
{
dsUD38 = boUD38.GetByID(eachOrderLine.OrderNum.ToString(), eachOrderLine.OrderLine.ToString(), releaseNum.ToString(), jobNum, serialNum);
var updateRow = (from r in dsUD38.UD38
select r).FirstOrDefault();
if (updateRow != null)
{
updateRow["Character10"] = "Test";
updateRow.Character10 = "Test";
updateRow["RowMod"] = "U";
updateRow.RowMod = "U";
boUD38.Update(ref dsUD38);
}
}
catch (Exception ex)
{
}
} // end foreach
} // end else
} // end foreach
First, I’d make sure I have data. GetByID will throw an exception if no record is found, however, in a try\empty catch it goes unnoticed. Can you confirm you ever get updateRow != null
Also when creating a new UD38, unless you are wiping your ds, accessing UD38[0] always give you the first record, not the new one
Good call. It is not null, though. I am running this through the configurator… Could that be a thing? Maybe I should do this another way. I read about a way to “unbreak” a configurator that was stuck by creating a second configurator and executing the code through it.
So I applied that concept to my current situation. I won’t be offended if you tell me I’m an idiot.
Great points. I didn’t have it [0] originally… I was troubleshooting and I never went back and fixed that. I will take care of it. Thanks! But yeah I can confirm I am retrieving the row in GetByID.
Not sure about that, but perhaps add a message to the catch with the error (or simply throw the exception) so you can see if there is something Epicor is trying to tell you (like maybe update failed because Row has been modified by another user)
So I decided to throw my Ex, as you suggested. This is what it revealed to me. … what?
Application Error
Exception caught in: Epicor.ServiceModel
Error Detail
Message: The underlying provider failed on EnlistTransaction.
Inner Exception Message: The partner transaction manager has disabled its support for remote/network transactions. (Exception from HRESULT: 0x8004D025)
Program: Epicor.ServiceModel.dll
Method: ShouldRethrowNonRetryableException
Client Stack Trace
at Epicor.ServiceModel.Channels.ImplBase1.ShouldRethrowNonRetryableException(Exception ex, DataSet[] dataSets) at Erp.Proxy.BO.ConfigurationRuntimeImpl.ExecutePageOnLoadEvents(String pageLoadEvent, String configID, Guid testID, PcValueDataSet pcValueDS) at Erp.Lib.Configurator.Runtime.ConfigurationServerFunctionsLib.ExecutePageOnLoadEvents(String pageLoadEvent, PcValueDataSet& pcValueDS) at Erp.UI.Cfg.TEST2ad00843c9e04ab7a99209faa390f91d._UNBREAKERPageEventCollection.Page1Load(PageLoadArgs LoadArgs) in c:\Users\dramirez\AppData\Local\Temp\ConfigDump\Client\_UNBREAKERPageEventCollection.cs:line 67 at Erp.Shared.Lib.Configurator.MethodCollection1.Invoke(String methodName, TMethodArgs args)
at Erp.Lib.Configurator.Runtime.ConfigurationController1.TriggerPageEvent(Int32 callerPageSeq, PageChangeArgs args) at Erp.Lib.Configurator.Runtime.ConfigurationController1.PageLoad(PageLoadArgs loadArgs)
at Erp.Lib.Configurator.Runtime.ConfigurationController`1.GetNextPage(Boolean skipping, Int32& proposedPageSeq)
Inner Exception
The partner transaction manager has disabled its support for remote/network transactions. (Exception from HRESULT: 0x8004D025)
Inner Exception
The partner transaction manager has disabled its support for remote/network transactions. (Exception from HRESULT: 0x8004D025)