Unexpected ArgumentExecption when accesing a Field Value in a SPListItem - sharepoint

I have the following helper method that returns the value from a field.
public static string GetValueFrom(SPListItem item, string fieldName)
{
string value = string.Empty;
if (item.Fields.ContainsField(fieldName))
{
SPField field = item.Fields.GetField(fieldName);
if (item[field.InternalName] != null)
{
value = item[field.InternalName].ToString();
}
}
return value;
}
However for one Field (normal Choice Field) I am getting a ArgumentExecption on this line
if (item[field.InternalName] != null)
I am using
SPListItem item = list.GetItemById(itemId);
To get the item.
I cant find why I am getting the exception when I am checking to see if the field exists?
Any ideas as to why I am getting this Exception for only one field.
Update.
When debugging
The call to GetField() returns the correct field object.
Field.InternalName contains the correct Internal name of the field
If I try and access the value using item["internal name of the field"] it still throws and exception for only this one field.

Sometimes strange things happens and we do not have logical answer to those questions. Try by deleting the list and then creating the list again from scratch. DO NOT try to save it as template and DO NOT try to create the list from that template.
One possible reason of such type of ugly messages is that the security/permissions are not allowing to manipulate that field/column.
Another possible reason of such type of unwanted/unexpected messages is that when the field was created for the first time, its data type was different and later on it was changed to choice. Technically there should be no problem in doing so but sometimes we face odd behavior.

Have you tried debugging? Questions you should answer (because we can't):
Is field a valid value, or null, after the call to GetField()?
If field is not null, what does field.InternalName actually return?
If field.InternalName returns a valid value, can you access it by hard-coding that value in the indexer? i.e. item["fieldInternalName"]
Finding that information may help you solve the problem yourself, but if it doesn't add it to your post so the community has a better chance of helping you.

I do experienced this many a times. The reason for this is if you are logged-in as a non Admin Account(System Account) the default List View Lookup Threshold for the User is 8 for the lookup columns. i.e for the default view the user can access upto the 8 lookup fields only. If you change the List Throttling to >8 it will be resolved. But increasing this will degrade the performance.
Go to Central Admin >> Manage Web Applications >> Select the Web Application >> General Settings Dropdown >> Resource Throttling >> Change the "List View Lookup Threshold" to more than 8
Thanks,
-Codename "Santosh"

Related

Netsuite Invalid API usage. You must use getValue to return the value set with setValue

So I have an odd issue, When I create a new transaction and save, this error in the title gets thrown. But when I edit this transaction after it was created, the getText does not throw this error. Is there something I'm doing wrong or something special needed to getText on a create new record? Here is my code. This is for the afterSubmit method on my User Event Script for Vendor Bill screen. I just noticed getValue does work on create, does not produce this error, just don't understand why? Is this the correct way to get the value on create? To use getValue and getText cannot be used on create? Only for edit?
if (scriptContext.type == scriptContext.UserEventType.CREATE ||
scriptContext.type == scriptContext.UserEventType.EDIT) {
// get bill to index
var Bill = scriptContext.newRecord;
// fails on this call below on create but works on edit
var refno = Bill.getText({ fieldId: 'tranid' });
}
This behavior is described in the API documentation here.
In dynamic mode, you can use getText() without limitation but, in standard mode, limitations exist. In standard mode, you can use this method only in the following cases:
You can use getText() on any field where the script has already used setText().
If you are loading or copying a record, you can use getText on any field except those where the script has already changed the value by using setValue().
Apparently the newRecord object falls under the second criteria. At this point, the object only has values set. tranid will have a value with the transaction's internal ID, but it won't have the transaction name stored. To get the text, you will have to use record.load() to get the full record, or use search.lookupFields() to get just the transaction name.

Validate value in field

Is there anyway to check when you type in to a field if there already are any document saved with that value in that field. Ex, if you type projectno i want to check if any other document already have that projectno. Any suggestion how i will validate that
Regards
You need a view in the database that is sorted in the first column by the field that you are using. I will assume it is a hidden view, called "(lookupUnique)". Build it and test it to make sure it is showing the field that you want in the first column, and that the values are sorted.
Now you need a way to do a lookup into this view. Ideally, you're wanting the lookup to fail -- because there is no document with the same value, in which case you allow the save to continue. But there's one other case where you might want to allow the save to continue. That's the case where the lookup succeeds because the lookup found the document that you are working on right now, which was previously saved and therefore is found in the view, and a user is now editing it again.
The #DbLookup function with the [RETURNDOCUMENTUNIQUEID] and [FAILSILENT] arguments is the IBM-recommended solution for this. I.e.,
foundId := #DbLookup("Notes":"NoCache";"":"";"(lookupUniqe)";theUniqueFieldNameGoesHereWithoutQuotes;1;[RETURNDOCUMENTUNIQUEID]);
If this formula returns "", then no match was found, therefore your code should return #Success to let the save continue. If it returns anything else, then compare the result with #DocumentUniqueId. If they match, then your code should return #Success to let the save continue. If they do not match, then you have found another document with the same value in the field, so your code should return #Failure with an appropriate error message.
Now here's the caveat: there have been known problems with [RETURNDOCUMENTUNIQUEID] in some versions of Domino, including a bug that caused Domino 6 servers to crash if an agent called ComputeWithForm on a document based on a form that used this feature. There's also a bug that causes it to return only the unid of the first match out of many matches, and so if you have duplicates this strategy in your code will allow users to re-save old documents that are already non-unique instead of forcing them to change them to make them unique, and that may or may not be what you want.
If either of those known issues might create a problem for you, then you would be better off not using [RETURNDOCUMENTUNIQUEID], and instead just do what Notes and Domino programmers did before IBM added the [RETURNDOCUMENTUNIQUEID] option in the first place: add another column to your (lookupUnique) view, and set the column value to #Text(#DocumentUniqueId). Change the 1 in the above #DbLookup formula to the number of the column that you added, and write your validation code to anticipate the possibility that you might get back an empty string, a single value, or a list of values.
If a type 45678 i return a value because there already are a document with that value. I don’t understan how i will validate it.
var dbname = session.getServerName() + "!!" + "proj\\webno.nsf";
getFieldValue = getComponent("oNo").getValue();
tmp = #DbLookup(dbname, "(webNo)", getFieldValue, ”obNo”);
if (tmp == getFieldValue)
{
Here i will do a validate. If value i return are the same as in the getFieldValue
and tmp or just getFieldValue is empty.
}
else
{
Here is it OK
}
Taking your code and modifying it. Assuming we're in the database we're creating the document in, just use #DbName() instead of trying to build the name from the session and some hard-coding. When using validation, the value of the control should be accessible simply with value. Then, just get all the values in the column and see if your value is in there.
I think the following should work.
<xp:inputText id="projectNumber" value="#{doc.ProjectNumber}">
<xp:this.validators>
<xp:validateExpression message="Value already in use">
<xp:this.expression><!CDATA[#{javascript:var usedValues = #DbColumn(#DbName(), "(webNo)", 1);
if ( #IsMember ( value, usedValues ) ) { return false };
return true;
</xp:this.expression>
</xp:validateExpression>
</xp:this.validators>
</xp:inputText>
Why don't you just generate a value for them? The simplest would be to use #Unique, but there are plenty of other ways besides having them have to create one.....

CRM 2011 JavaScript How to access data stored in an entity passed from a lookup control?

As the question suggests, I need to find out how to access entity data that has been passed into a JavaScript function via a lookup.
JavaScript Code Follows:
// function to generate the correct Weighting Value when these parameters change
function TypeAffectedOrRegionAffected_OnChanged(ExecutionContext, Type, Region, Weighting, Potential) {
var type = Xrm.Page.data.entity.attributes.get(Type).getValue();
var region = Xrm.Page.data.entity.attributes.get(Region).getValue();
// if we have values for both fields
if (type != null && region != null) {
// create the weighting variable
var weighting = type[0].name.substring(4) + "-" + region;
// recreate the Weighting Value
Xrm.Page.data.entity.attributes.get(Weighting).setValue(weighting);
}
}
As you can see with the following line using the name operator I can access my Type entity's Type field.
// create the weighting variable
var weighting = type[0].name.substring(4) + "-" + region;
I am looking for a way now to access the values stored inside my type object. It has the following fields new_type, new_description, new_value and new_kind.
I guess I'm looking for something like this:
// use value of entity to assign to our form field
Xrm.Page.data.entity.attributes.get(Potential).setValue(type[0].getAttribute("new_value"));
Thanks in advance for any help.
Regards,
Comic
REST OData calls are definitely the way to go in this case. You already have the id, and you just need to retrieve some additional values. Here is a sample to get you started. The hardest part with working with Odata IMHO is creating the Request Url's. There are a couple tools, that you can find on codeplex, but my favorite, is actually to use LinqPad. Just connect to your Org Odata URL, and it'll retrieve all of your entities and allow you to write a LINQ statement that will generate the URL for you, which you can test right in the browser.
For your instance, it'll look something like this (it is case sensitive, so double check that if it doesn't work):
"OdataRestURL/TypeSet(guid'" + type[0].Id.replace(/{/gi, "").replace(/}/gi, "") + "'select=new_type,new_description,new_value,new_kind"
Replace OdataRestURL with whatever your odata rest endpoint is, and you should be all set.
Yes Guido Preite is right. You need to retrieve the entity by the id which come form the lookup by Rest Sync or Async. And then get Json object. However for make the object light which is returned, you can mention which fields to be backed as part of the Json. Now you can access those fields which you want.

How to make #DbLookup in XPages verify the existence of a value in another database?

I have an XPage that is doing an #DbLookup with a user's input and trying to find that value in a view in a different database yet on the same server.
I have already verified that the view is in fact sorted by the first column and therefore #DbLookup friendly. The following code below appears in the server-side Javascript OnClick event handler for a button on my XPage.
My problem is that the an error occurs when trying to assign the value of lRep to the 'firstNameLabel'. lRep is returning a null value from the dbLookup even though the a record under the 'FirstName' field exists with the key 'P301993'. This dbLookup should be finding a returning a single 'FirstName' result. However, it is not.
var resultLabel = getComponent("firstNameLabel");
var dbName = new Array(#DbName()[0],"UKCSandbox.nsf");
var lRep = #DbLookup(dbName,"customerLookup","P301993","FirstName");
resultLabel.setValue(lRep.toString());
Unless your formatting was lost in copy and paste, your code has flaws. This is not Java, this is JavaScript. Line endings matter and functions don't act on the object, but return a value. Also #DbLookup returns a string when you have exactly one match, so checking for string doesn't help you.
Your code should look like that:
var ukcNumber = Registration.getItemValueString('UKCNumber').toUpperCase();
var resultLabel = getComponent("ukcNumberLabel");
var dbName = #DbName();
dbName[1] = "UKC\\UKCSandbox.nsf";
var lRep = #DbLookup(dbName,"customerLookup",ukcNumber,1);
resultLabel.setValue((lRep) ? "Success" : "Failed");
Does that work for you?
Update: 2 things to check:
does the lookup work in the same database using #DbName?
XPages have the same security constraints as Java agents. Do you have enough rights in the server document to do a 'get value from other database'? Default is No!
Have you tried making the dblookup work outside of xpages, i.e. with ScanEZ or in the Notes client?
Check your ukcNumber variable so it contains a value.
Edit
Check so the user has rights to do the lookup in the other database.
Also try a similar code on an old Notes Form and see if you get the same result.
Why can't you use keyword '[FAILSILENT]' in your #DBLookup call. It'll return "", if no entry matches with your key.
If you still have issues, use SSJS/java code to see where it's breaking up.

sharepoint - add custom column to list via object model

I'm having trouble figuring out how to add a custom column type to a list with the object model.
SPFieldCollection.Add() has a parameter SPFieldType, but that must be one of the enumerated values in the Microsoft.SharePoint.SPFieldType enumeration, thus it cannot be used to create columns of a custom type.
I next attempted using SPFieldCollection.CreateNewField() but when I call SPField.Update() on the returned value I get an exception: "ArgumentException was unhandled. Value does not fall within the expected range.".
I see a reference to SPFieldCollection.AddFieldAsXml() here: How do I add custom column to existing WSS list template but there's hardly any info and I'm not sure that's the right track to take.
UPDATE: I found a post on AddFieldAsXml: http://weblogs.asp.net/bsimser/archive/2005/07/21/420147.aspx and it turns out it's very easy and worked well for me. Posting anyway in hopes it will help someone else.
SPFieldCollection.AddFieldAsXml() is the way to go as far as I can tell. See here for an example: http://weblogs.asp.net/bsimser/archive/2005/07/21/420147.aspx
Try with:
SPField newField = null;
newField= web.Fields.CreateNewField("MyFieldTypeName", fieldName);
web.Fields.Add(newField);
newField = web.Fields[fieldName];
// set some properties
newField.ShowInDisplayForm = false;
newField.ShowInViewForms = true;
newField.Update();

Resources