How do I Loop through a multi-value People Field or Lookup field in SharePoint 2013 designer using REST - sharepoint-2013

I have a multi-valued people picker and a multi-valued Lookup field that I need to read all the entries in a 2013 workflow. I know how to create a workflow that retrieves the data and iterate through each list item using REST and a dictionary. Given I'm iterating through each item, I need to now iterate through each multi-valued field.
In the past, I have done this using a loop iterator and a second dictionary entry representing the data in the multi-valued field, but I don't have access to this code anymore. I can use a loop and use the find function parsing through my responseContent, but this is not reliable since my reponseContent will have multiple records in it and I know it can be done using a second dictionary entry.
My REST query is:
_api/lists/GetByTitle('EmailSetup')/Items?$select=EmailYN,EmailSubject,EmailBody,EmailTo/EMail,Emailcc/EMail,EmailToWorkflowPerson/Title,EmailccWorkflowPersons/Title&$filter=(Title%20eq%20%27BSM%20Review%27)%20and%20(WorkflowName%20eq%20%27ProcessBSMRequests%27)&$expand=EmailTo,Emailcc,EmailToWorkflowPerson,EmailccWorkflowPersons
Where my multi-valued fields are the Emailcc and EmailccWorkflowPerson, (people picker and lookup respectively).
I have my first dictionary as the following data structure that captures the requestHeaders
Accept String application/json;odata=verbose
Content-Type String application/json;odata=verbose
In my first loop I get all my attributes, but not certain how to get the multi-valued fields Emailcc and EmailccWorkflowPersons.
Yes, I can parse through my response, but there's a better way to somehow put these multi-value fields into a structure and then loop through these.
What I need is what is that structure (dictionary) and how do you get the data into that structure and then how do you loop through that structure.
The final result should be of the sort (psuedocode) where Index is which record I am on and Index2 is which multi-value I am on.
d/results([%Varaible: Index%])/Emailcc/Email[%Variable: Index2%])xxx

With a lot of debugging I have gotten half my answer and maybe someone can help me with the other half. The data structure of the data when it comes back via the REST looks like (some masking of our own data):
responseContent={"d":{"results":[{
"__metadata":{"id":"Web\/Lists(guid'c7bb71c8-a9dd-495f-aa5f-4dcacdf8db5c')\/Items(1)","uri":"https:\/\/xxxxx.xxxxxx.xxxxxxxxx.xxx\/hc\/teams\/MES\/_api\/Web\/Lists(guid'c7bb71c8-a9dd-495f-aa5f-4dcacdf8db5c')\/Items(1)","etag":"\"13\"","type":"SP.Data.EmailSetupListItem"},
"EmailTo":{"__metadata":{"id":"b493bee4-ec1a-4b76-a028-11766bdb7e5b","type":"SP.Data.UserInfoItem"},"EMail":"xyxee.dyff#homeward.com"},
"EmailToWorkflowPerson":{"__deferred":{"uri":"https:\/ \/xxxxx.xxxxxx.xxxxxxxxx.xxx\/hc\/teams\/MES\/_api\/Web\/Lists(guid'c7bb71c8-a9dd-495f-aa5f-4dcacdf8db5c')\/Items(1)\/EmailToWorkflowPerson"}},
"Emailcc":{"results":[{"__metadata":{"id":"790a690a-515b-4d07-bba3-73bf325fbbed","type":"SP.Data.UserInfoIt em"},"EMail":"xyxee.dyffns1#homeward.com"},{"__metadata":{"id":"3d77e75c-5fa8-4df6-937c-97e572714843","type":"SP.Data.UserInfoItem"},"EMail":"xyxee.dyffr#homeward.com"}]},
"EmailccWorkflowPersons":{"results":[{"__metadata":{"id":"06582ed9-09 10-4932-9b43-0cfb072942c7","type":"SP.Data.WorkflowPersonsListItem"},"Title":"Assistant Administrator"},{"__metadata":{"id":"13d03566-1703-4550-a21f-08ea286d4940","type":"SP.Data.WorkflowPersonsListItem"},"Title":"Initiator"}]},
"EmailYN":"No",
"EmailSubject":"BSM Request # %%ID%%",
"EmailBody":"<div class=\"ExternalClass645790473F7D4B62BE6224DD7B93990F\">%%IDLINK%%<br><\/div><div class=\"ExternalClass645790473F7D4B62BE6224DD7B93990F\">and the BSM# %%ID%%<br><\/div><div class=\"ExternalClass64 5790473F7D4B62BE6224DD7B93990F\"><br><\/div>"
}]}}
I created another dictionary variable, EmailResults just as the first one to store the multi-value emailcc addresses.
Then the following Get:
Get d/results([%variable: Index%)/Emailcc/results from Variable:responseContent (Output to Variable: EmailccResults)
To get the record count, I use Count Items in the EmailccResults
I set my second index to start at zero and loop through the number baseed on the count in EmailccResults.
To set my intermediate email address (getting one value at a time from the mult-value People picker).
Get d/results([%variable: Index%)/Emailcc/results(%Variable: Index2%)/EMail from Variable: responseContent (Output to Variable: EmailCc)
then I increment the Index2 variable and go to the next record. This works perfectly.
Now my problem is I have a multi-value Lookup that is included in this query (see what the results are above). I attempt the same logic and I am successfully getting the count, but not the Title fields.
My get is:
Get d/results([%variable: Index%)/EmailccWorkflowPersons/results from Variable:responseContent (Output to Variable: EmailccResults)
My actual assignment is:
Get d/results([%variable: Index%)/EmailccWorkflowPersons/results(%Variable: Index2%)/Title from Variable: responseContent (Output to Variable: tmpvar)
** the Lookup works exactly the same way. My problem was that my get above had some blank lines in the text box.

Related

Mapping user spreadsheet columns to database fields

I’m not sure where to start on this project. I know how to read the contents of the excel spreadsheet, I know how to identify the header row, I know how to loop over the contents. I believe I have the UX portion worked out but I am not sure how to process the data.
I’ve googled and only found .Net solutions but I’m looking for a ColdFusion/Lucee solution.
I have a working form allowing me to map a user's spreasheet column to my database values (this is being kept simple for this post; user does not have direct access to the database).
Now that I have my data, I'm not sure how to loop over the data results. I believe there will be several loops (an outer and an inner). Then of course I also need to loop over the file contents but I think if I can get the headings mapped out,I can figure out the remaining.
Any good links, tutorials, or guides would be greatly appreciated.
Some pseudo code might be enough to get me started.
User uploads form
System reads headers and content.
User is presented form with a list of columns from their uploaded spreadsheet to match with available database fields (eg “column1” matches “customer name”.
User submits form.
Now what?
UPDATED
Here is what the data looks like AFTER the mapping has been done in my form. The column deliiter is the ::: and within the column the ||| indicates the ID associated with the selected column value. I've included the id and the column value since I plan on displaying the mapping again as a confirmation. Having the ID saves a trip to the database.
If I understand correctly, your question is: how do you provide the user a form allowing them to map their spreadsheet columns to that of the database
Since you have their spreadsheet column names, and you have the database column names, then this problem is essentially a UI/UX problem. You need to show both lists, and allow the user to map them. I can imagine several approaches to this. My first thought would be some sort of drag/drop operation, as follows:
Create a list of boxes, one for each field in your database table, and include the field name in (or above) the box. I'll call this the db field list. Then, create another list for each column from the spreadsheet, which I'll call the spreadsheet column list. The user would drag/drop items from the spreadsheet column list to the db field list.
When a mapping has been completed by the user, you would store the column/field names in as data for the DOM element of the db field list box. Then upon submission, you would acquire the mapping data by visiting each box and adding it to an array. Then you would serialize that array into JSON and send that to your form submission handler.
This could be difficult or easy, depending on your knowledge of UI implementations using JavaScript. jQuery makes this easy (if you know jQuery). There's even a jquery UI plugin that does this: https://jqueryui.com/droppable/.
A quick search for javascript drag drop would help, and here's a few articles I found:
https://www.w3schools.com/html/html5_draganddrop.asp
https://medium.com/quick-code/simple-javascript-drag-drop-d044d8c5bed5
You would also need to submit the array of mappings using javascript. You could search for that as well, and here's an article I found:
https://codereview.stackexchange.com/questions/94493/submit-an-array-as-an-html-form-value-using-javascript

DynamoDB create index on map or list type

I'm trying to add an index to an attribute inside of a map object in DynamoDB and can't seem to find a way to do so. Is this something that is supported or are indexes really only allowed on scalar values? The documentation around this seems to be quite sparse. I'm hoping that the indexing functionality is similar to MongoDB but so far the approaches I've taken of referencing the attribute to index using dot syntax has not been successful. Any help or additional info that can be provided is appreciated.
Indexes can be built only on top-level JSON attributes. In addition, range keys must be scalar values in DynamoDB (one of String, Number, Binary, or Boolean).
From http://aws.amazon.com/dynamodb/faqs/:
Q: Is querying JSON data in DynamoDB any different?
No. You can create a Global Secondary Index or Local Secondary Index
on any top-level JSON element. For example, suppose you stored a JSON
document that contained the following information about a person:
First Name, Last Name, Zip Code, and a list of all of their friends.
First Name, Last Name and Zip code would be top-level JSON elements.
You could create an index to let you query based on First Name, Last
Name, or Zip Code. The list of friends is not a top-level element,
therefore you cannot index the list of friends. For more information
on Global Secondary Indexing and its query capabilities, see the
Secondary Indexes section in this FAQ.
Q: What data types can be indexed?
All scalar data types (Number, String, Binary, and Boolean) can be
used for the range key element of the local secondary index key. Set,
list, and map types cannot be indexed.
I have tried doing hash(str(object)) while I store the object separately. This hash gives me an integer(Number) and I am able to use a secondary index on it. Below is a sample in python, it is important to use a hash function which generates the same hash key every time for the value. So I am using sha1.
# Generate a small integer hash:
import hashlib
def hash_8_digits(source):
return int(hashlib.sha1(source.encode()).hexdigest(), 16) % (10 ** 8)
The idea is to keep the entire object small while still the entity intact. i.e. rather than serializing and storing the object as string and changing whole way the object is used I am storing a smaller hash value along with the actual list or map.

Reading Sharepoint List Calculated field from PowerShell

I am trying to pull data from a SharePoint list. The field is a calculated column that takes a yes or no answer and changes the words to archived and non-archived.
I can see the data being formatted correctly in the calculated column in IE but when I try to pull the data it shows up as nothing when I check the variable data.
$site = get-spsite https://extranet./sites/site
$web = get-spweb -Identity https://extranet/sites/site
$list=$web.getlist("https://extranet/sites/site/lists/List");
$View = $list.Views["LISTVIEW"]
$listitems = $list.Getitems($view)
foreach ($listitem in $listitems) {
I have tried this also but get an indexing a null variable error.
$mailboxdb = $listitem.Fields["mailboxdb"] -as [Microsoft.SharePoint.SPFieldCalculated];
$mailboxdb.GetFieldValueAsText($listitem["mailboxdb"]);
I see this also in the $listitems output. ows_MailboxDb='string;#Archived'
But when I check $mailboxdb its empty.
Found this but I don't know what it means by stored results.
In Powershell, although you can reference any field in the list in your script, you can only compare retrieve values from "static" fields - that is, you cannot use calculation fields. PowerShell will not complain - but you will not get results in your script. This is because the .Net library for Sharepoint will not do the field calculation for you - that only happens inside the Sharepoint UI itself.
If you need to have access to a "calculated" field, you actually need to have two fields - the calculated field (usually hidden) and a "stored result" field, which must be updated from the calculated value in the last step of the "Update" workflow. Then you can use the "stored value" field in PowerShell - and also, incidentally, in View calculations in Sharepoint.
You basically have two options here. You can have Powershell do the calculation for you, which is probably the simpler of the two options given the basic nature of your calculation.
The second option, as mentioned at the end of your post is to create a new field which can store the result of the calculation. In your case, you could call it status. Then you would create a workflow that runs whenever a list item is updated or created that stores the results of the calculated field in the results field. This seems redundant to me if you have this field for no other reason than to use the value of the calculated field in a PowerShell script.

Scan a dynamodb based on a list

I have a String Set attribute i.e SS in a dynamodb table. I need to scan the database to check the value present in the any one list of the items.
Which comparison operator should I use for this scan?
example the db has items like this:
name
[email1, email2]
phone
I need to search for a items containing a particular email say email1 alone not giving the entire tuple.
It seems like you are looking for the CONTAINS operator of Scan operation. It basically is the equivalent of in in Python.
This said, if you need to perform this often, you probably should de-normalize your data to make it faster.
For example, you could build a second table like this:
hash_key: name
range_key: email
Of course, you would have to maintain this index yourself and query it manually.

Looping through data over multiple pages in Django

I'm trying to find the best way to go about my problem and I would love your input. I am trying to allow users to scan multiple barcodes into a text area. After they are submitted they are split into an array. The user then inputs how many iterations of each value in the array are to be inserted into a MySQL database. I've achieved this using PHP and session variables, looping through the array one step at a time. With Django I've found it a little more difficult and I am wondering if I should just have a "temporary" table in my database that gets refilled with the values from the array of barcodes. The following pages then pull each value from the table instead of using any sort of session variables.
Edit:
I apologize for the confusing question. Let me try and clear it up a bit:
I need to render a view based on each value in the user-submitted array. When it is first submitted, a view is rendered for the first value. When the user hits "Next" a view will be rendered for the second value in the array, and so on.
As for the database issue, each value can have two "types." The user will declare how many of each type is added to the database in each of the views I am trying to render.
Thank you.
this is nothing about django.
forget that temporary table.
add a field "filled" to ur table
select 1st not-filled row, and show "refill" page by this row
then update user input number back to db, set "filled" to "true" at same time.
You probably can port your PHP solution using a Django session object.
I'm not sure if that "one item at a time" is a feature or a "it was easier to code that way" thing, but in the second case - you may want to use Django Formsets to display all items at once and avoid looping through the array.