Start workflow with web services Sharepoint 2010 - web-services

I am attempting to run a visual studio sequential workflow on items in a library, but have hit a wall. since the client object model doesn't seem to support starting workflows, I am attempting to use the web service call to "../_vti_bin/workflow.asmx" web service.
Everything seems ok up to the point where it calls
StartWorkflow(item, templateid, workflowParameters)
I get an error saying parameters can't be null. My workflow has no init form, so im not sure what params to pass. can someone help me out here?
here is my code:
Private Sub LoadDataFromSite()
Try
Dim frm As New DateForm
frm.ShowDialog()
fromDate = frm.DateTimePicker1.Value.Date
toDate = frm.DateTimePicker2.Value.Date
Dim siteUrl As String = "http://host.dom.local/payroll/"
Dim clientContext As New ClientOM.ClientContext(siteUrl)
Dim oList As ClientOM.List = clientContext.Web.Lists.GetByTitle("Timesheets")
Dim oListItem As ListItem
Dim camlQuery As New ClientOM.CamlQuery()
camlQuery.ViewXml = "<View/>"
Dim collListItem As ClientOM.ListItemCollection = oList.GetItems(camlQuery)
clientContext.Load(collListItem)
clientContext.ExecuteQuery()
For Each oListItem In collListItem
Console.WriteLine("ID: {0} " & vbCrLf & "Title: {1} " & vbCrLf & "", oListItem.Id, oListItem("Title"))
If CDate(oListItem("Timesheet_x0020_Date")).Date >= fromDate And _
CDate(oListItem("Timesheet_x0020_Date")).Date <= toDate Then
MsgBox("found a timesheet in the specified date range = " & oListItem("Timesheet_x0020_Date"))
Dim sguid As String = "{2009B982-3A49-4217-99AC-7E52C0EE44EF}"
Dim workflowTemplateGuid As New Guid(sguid)
Dim _itemURI As String = "http://host.dom.local/payroll/" & oListItem("Title")
Dim workflow As WSWorkflow.Workflow = New WSWorkflow.Workflow
workflow.Credentials = System.Net.CredentialCache.DefaultNetworkCredentials
workflow.StartWorkflow(_itemURI, workflowTemplateGuid, Nothing)
End If
Next oListItem
Catch exs As Microsoft.SharePoint.Client.ServerException
MsgBox("Error starting export workflow on list items. It may not be finished yet, and you may need to export the timesheets manually." & exs.Message)
Catch exss As Microsoft.SharePoint.Client.ClientRequestException
MsgBox("Error starting export workflow on list items. It may not be finished yet, and you may need to export the timesheets manually." & exss.Message)
Catch ext As Microsoft.SharePoint.SoapServer.SoapServerException
MsgBox("Error starting export workflow on list items. Soap exception. " & ext.Message)
End Try
End Sub
so I can't pass NOTHING to the function call, so what do here?

There are two problems with your code.
1) Item URI/URL - its should be ows_EncodedAbsUrl of Item, you can get it from Lists.asmx
2) association data - can not be null.
you can find detailed explanation at.
http://sharepointbuzzer.com/2013/10/15/start-workflow-using-client-object-model/
I hope it solves your error.

Related

How can I use code to export a SharePoint list to Excel

I found a previous question and it looks to be what I'm looking for. However when I run the code, I get a debug error (Highlights the last line from "Set ObjMyList . . . . ("A1"))". Below is the code I'm using with the specific path & GUIDs. I tried adjusting the sharepoint address, but the one listed is the one that points to the library. I also tried just the home address (Stopping at "TEP") and all the way to including "All Items.aspx". I'm sure I am missing something "simple", but just thought I'd try to ask here.
Dim objMyList As ListObject
Dim objWksheet As Worksheet
Dim strSPServer As String
Const SERVER As String = "https://twdc.sharepoint.com/sites/WDPR-dclrecruiting/Test/TEP/Trip%20Event%20Planning%20Library"
Const LISTNAME As String = "{6B39FDF1-29AE-418C-9D99-92293FED5C81}"
Const VIEWNAME As String = "{CCFD1C7F-74CA-4921-A599-628C800C818A}"
strSPServer = "http://" & SERVER & "/_vti_bin"
Set objWksheet = Worksheets.Add
Set objMyList = objWksheet.ListObjects.Add(xlSrcExternal, _
Array(strSPServer, LISTNAME, VIEWNAME), False, xlYes, Range("A1"))
Below code works in my local
Sub ExportList()
Dim objWksheet As Worksheet
Dim strSPServer As String
Const SERVER As String = "sp/sites/team"
Const LISTNAME As String = "{3e47ff9c-9aab-4a40-9d6a-c47e9b793484}" 'From source code
Const VIEWNAME As String = "{67709eda-c975-4669-85e5-d95e263dadc6}" 'From source code
' The SharePoint server URL pointing to the SharePoint list to import into Excel.
strSPServer = "http://" & SERVER & "/_vti_bin"
Set objWksheet = Sheets("Sheet1")
' Add a list range to the newly created worksheet
' and populated it with the data from the SharePoint list.
Set objMyList = objWksheet.ListObjects.Add(xlSrcExternal, Array(strSPServer, LISTNAME, VIEWNAME), True, , Range("A1"))
Set objMyList = Nothing
Set objWksheet = Nothing
End Sub

Entity Framework 6 only allows 5 attemps when SaveChanges() fails and restart process (concurrency)

I'm adding new record with entity framework and I need this when I have multiple inserting records and many users on diferent machines at same time (concurrency). So I'm using Catch to restart SaveChanges() process.
In example bellow you can see what I'm triyng to do:
Public Sub AdicionaAux(ByRef Attempts As Integer)
Dim inBlnRepete As Boolean = False
Try
Using ctx As New BD.Dinamica.Aplicacao
Using trans As DbContextTransaction = ctx.Database.BeginTransaction(IsolationLevel.RepeatableRead)
Try
Dim t As tbArtigos = ctx.tbArtigos.FirstOrDefault
ctx.tbArtigos.Attach(t)
ctx.Entry(t).State = EntityState.Added
ctx.SaveChanges() 'FAILS AND GO TO CATCH
Catch ex As Exception
trans.Rollback()
Throw
End Try
End Using
End Using
Catch
inBlnRepete = True 'RepeteFuncaoPorConcorrencia(ex, Tentativas)
If inBlnRepete And Attempts < 10 Then
AdicionaAux(Attempts) 'RESTART PROCESS
Else
Throw
End If
End Try
End Sub
When I'm on 6th time on catch my application crashs and IIS stops.
If I'm on Visual Studio debbuging, debugger stops.
I don't understand why this happens? Why my app crashes and IIS stops?
It's EF6 Configuration? IIS configuration? SQL configuration?
In example bellow Using sql I have no problem:
Public Sub AdicionaAux(ByRef Attempts As Integer)
Try
Dim appServidorSQL As String = ConfigurationManager.AppSettings("ServidorSQL")
Dim appInstanciaSQL As String = ConfigurationManager.AppSettings("InstanciaSQL")
Dim appBDEmpresa As String = ConfigurationManager.AppSettings("BDEmpresa")
Using connection As New SqlConnection("Server=" & appServidorSQL & "\" & appInstanciaSQL & ";User ID=sa;Initial Catalog=" & appBDEmpresa & ";")
connection.Open()
Dim command As SqlCommand = connection.CreateCommand()
Dim transaction As SqlTransaction
transaction = connection.BeginTransaction("SampleTransaction")
command.Connection = connection
command.Transaction = transaction
Try
command.CommandText = _
"Insert into tbDestinos (Codigo, Descricao, Ativo, Sistema, DataCriacao, UtilizadorCriacao) VALUES ('POR', 'Description',1,1,getdate(),'xxx')"
command.ExecuteNonQuery()
transaction.Commit()
Catch ex As Exception
transaction.Rollback()
Throw
End Try
End Using
Catch
AdicionaAux(Attempts)
End Try
End Sub
Any help?

Webscraping with VBA morningstar financial

I'm trying to scrape the inside ownership from Morningstar at this url:
http://investors.morningstar.com/ownership/shareholders-overview.html?t=TWTR&region=usa&culture=en-US
This is the code I'm using:
Sub test()
Dim appIE As Object
Set appIE = CreateObject("InternetExplorer.Application")
With appIE
.Navigate "http://investors.morningstar.com/ownership/shareholders-overview.html?t=TWTR&region=usa&culture=en-US"
.Visible = True
End With
While appIE.Busy
DoEvents
Wend
Set allRowOfData = appIE.Document.getElementById("currentInsiderVal")
Debug.Print allRowOfData
Dim myValue As String: myValue = allRowOfData.Cells(0).innerHTML
appIE.Quit
Set appIE = Nothing
Range("A30").Value = myValue
End Sub
I get run-time error 13 at line
Set allRowOfData = appIE.Document.getElementById("currentInsiderVal")
but I can't see any mismatch. What is going on?
You can just do it with XHR and RegEx instead of cumbersome IE:
Sub Test()
Dim sContent
With CreateObject("MSXML2.XMLHTTP")
.Open "GET", "http://investors.morningstar.com/ownership/shareholders-overview.html?t=TWTR&region=usa&culture=en-US", False
.Send
sContent = .ResponseText
End With
With CreateObject("VBScript.RegExp")
.Pattern = ",""currInsiderVal"":(.*?),"
Range("A30").Value = .Execute(sContent).Item(0).SubMatches(0)
End With
End Sub
Here is the description how the code works:
First of all MSXML2.XMLHTTP ActiveX instance is created. GET request opened with target URL in synchronous mode (execution interrupts until response received).
Then VBScript.RegExp is created. By default .IgnoreCase, .Global and .MultiLine properties are False. The pattern is ,"currInsiderVal":(.*?),, where (.*?) is a capturing group, . means any character, .* - zero or more characters, .*? - as few as possible characters (lazy matching). Other characters in pattern to be found as is. .Execute method returns a collection of matches, there is only one match object in it since .Global is False. This match object has a collection of submatches, there is only one submatch in it since the pattern contains the only capturing group.There are some helpful MSDN articles on regex:
Microsoft Beefs Up VBScript with Regular Expressions
Introduction to Regular Expressions
Here is the description how I created the code:
First I found an element containing the target value on the webpage DOM using browser:
The corresponding node is:
<td align="right" id="currrentInsiderVal">143.51</td>
Then I made XHR and found this node in the response HTML, but it didn't contain the value (you can find response in the browser developer tools on network tab after you refresh the page):
<td align="right" id="currrentInsiderVal">
</td>
Such behavior is typical for DHTML. Dynamic HTML content is generated by scripts after the webpage loaded, either after retrieving a data from web via XHR or just processing already loaded withing webpage data. Then I just searched for the value 143.51 in the response, the snippet ,"currInsiderVal":143.51, located within JS function:
fundsArr = {"fundTotalHistVal":132.61,"mutualFunds":[[1,89,"#a71620"],[2,145,"#a71620"],[3,152,"#a71620"],[4,198,"#a71620"],[5,155,"#a71620"],[6,146,"#a71620"],[7,146,"#a71620"],[8,132,"#a71620"]],"insiderHisMaxVal":3.535,"institutions":[[1,273,"#283862"],[2,318,"#283862"],[3,351,"#283862"],[4,369,"#283862"],[5,311,"#283862"],[6,298,"#283862"],[7,274,"#283862"],[8,263,"#283862"]],"currFundData":[2,2202,"#a6001d"],"currInstData":[1,4370,"#283864"],"instHistMaxVal":369,"insiders":[[5,0.042,"#ff6c21"],[6,0.057,"#ff6c21"],[7,0.057,"#ff6c21"],[8,3.535,"#ff6c21"],[5,0],[6,0],[7,0],[8,0]],"currMax":4370,"histLineQuars":[[1,"Q2"],[2,"Q3"],[3,"Q4"],[4,"Q1<br>2015"],[5,"Q2"],[6,"Q3"],[7,"Q4"],[8,"Q1<br>2016"]],"fundHisMaxVal":198,"currInsiderData":[3,143,"#ff6900"],"currFundVal":2202.85,"quarters":[[1,"Q2"],[2,""],[3,""],[4,"Q1<br>2015"],[5,""],[6,""],[7,""],[8,"Q1<br>2016"]],"insiderTotalHistVal":3.54,"currInstVal":4370.46,"currInsiderVal":143.51,"use10YearData":"false","instTotalHistVal":263.74,"maxValue":369};
So the regex pattern created based on that it should find the snippet ,"currInsiderVal":<some text>, where <some text> is our target value.
Had a look on the site and the element you are trying to retrieve has a typo in it; instead of currentInsiderVal try using currrentInsiderVal and you should retrieve the data correctly.
Probably worth considering some error trapping to catch stuff like this for any other fields you retrieve?
After your comment I took a closer look. Your issue seemed like it was trying to trap the id of the individual cell rather than navigating down the object tree. I've modified the code to retrieve the row of the table you are after and then set myValue to be the correct cell within that row. Seemed to be working when I tried it out. Give this a shot?
Sub test()
Dim appIE As Object
Set appIE = CreateObject("internetexplorer.application")
With appIE
.Navigate "http://investors.morningstar.com/ownership/shareholders-overview.html?t=TWTR&region=usa&culture=en-US"
.Visible = True
End With
While appIE.Busy
DoEvents
Wend
Set allRowOfData = appIE.Document.getelementbyID("tableTest").getElementsByTagName("tbody")(0).getElementsByTagName("tr")(5)
myValue = allRowOfData.Cells(2).innerHTML
appIE.Quit
Set appIE = Nothing
Range("A30").Value = myValue
End Sub

Extract multiple email in a single Outlook message to Excel?

I need a macro in Outlook that extract all the email address in the outlook message then post it in excel.
The following code only extracts the very 1st email address it finds in the body.
My desired output should be:
adam.peters#sample.com
adam.dryburgh#sample.com
amy.norton#sample.com
My sample email is:
Delivery has failed to these recipients or groups:
adam.peters#sample.com The e-mail address you entered couldn't be
found. Please check the recipient's e-mail address and try to resend
the message. If the problem continues, please contact your helpdesk.
adam.dryburgh#sample.com The e-mail address you entered couldn't be
found. Please check the recipient's e-mail address and try to resend
the message. If the problem continues, please contact your helpdesk.
amy.norton#sample.com The e-mail address you entered couldn't be
found. Please check the recipient's e-mail address and try to resend
the message. If the problem continues, please contact your helpdesk.
The following organization rejected your message:
mx2.dlapiper.iphmx.com.
code:
Sub Extract_Invalid_To_Excel()
Dim olApp As Outlook.Application
Dim olExp As Outlook.Explorer
Dim olFolder As Outlook.MAPIFolder
Dim obj As Object
Dim stremBody As String
Dim stremSubject As String
Dim i As Long
Dim x As Long
Dim count As Long
Dim RegEx As Object
Set RegEx = CreateObject("VBScript.RegExp")
Dim xlApp As Object 'Excel.Application
Dim xlwkbk As Object 'Excel.Workbook
Dim xlwksht As Object 'Excel.Worksheet
Dim xlRng As Object 'Excel.Range
Set olApp = Outlook.Application
Set olExp = olApp.ActiveExplorer
Set olFolder = olExp.CurrentFolder
'Open Excel
Set xlApp = GetExcelApp
xlApp.Visible = True
If xlApp Is Nothing Then GoTo ExitProc
Set xlwkbk = xlApp.workbooks.Add
Set xlwksht = xlwkbk.Sheets(1)
Set xlRng = xlwksht.Range("A1")
xlRng.Value = "Bounced email addresses"
'Set count of email objects
count = olFolder.Items.count
'counter for excel sheet
i = 0
'counter for emails
x = 1
For Each obj In olFolder.Items
xlApp.StatusBar = x & " of " & count & " emails completed"
stremBody = obj.Body
stremSubject = obj.Subject
'Check for keywords in email before extracting address
If checkEmail(stremBody) = True Then
'MsgBox ("finding email: " & stremBody)
RegEx.Pattern = "\b[A-Z0-9._%+-]+#[A-Z0-9.-]+\.[A-Z]{2,4}\b"
RegEx.IgnoreCase = True
RegEx.MultiLine = True
Set olMatches = RegEx.Execute(stremBody)
For Each match In olMatches
xlwksht.cells(i + 2, 1).Value = match
i = i + 1
Next match
'TODO move or mark the email that had the address extracted
Else
'To view the items that aren't being parsed uncomment the following line
'MsgBox (stremBody)
End If
x = x + 1
Next obj
xlApp.ScreenUpdating = True
MsgBox ("Invalid Email addresses are done being extracted")
ExitProc:
Set xlRng = Nothing
Set xlwksht = Nothing
Set xlwkbk = Nothing
Set xlApp = Nothing
Set emItm = Nothing
Set olFolder = Nothing
Set olNS = Nothing
Set olApp = Nothing
End Sub
Function GetExcelApp() As Object
' always create new instance
On Error Resume Next
Set GetExcelApp = CreateObject("Excel.Application")
On Error GoTo 0
End Function
untested
replace
RegEx.Pattern = "\b[A-Z0-9._%+-]+#[A-Z0-9.-]+\.[A-Z]{2,4}\b"
RegEx.IgnoreCase = True
RegEx.MultiLine = True
with
RegEx.Pattern = "\b[A-Z0-9._%+-]+#[A-Z0-9.-]+\.[A-Z]{2,4}\b"
RegEx.IgnoreCase = True
RegEx.MultiLine = True
RegEx.Global = True
I have noticed the following line of code:
Set olApp = Outlook.Application
If you run the code in Outlook, you need to use the Application property to get an instance of the Application class. Or you need to use the New operator to create a new instance, for example:
Set ol = New Outlook.Application
or
Set objOL = CreateObject("Outlook.Application")
See How to automate Outlook from another program for more information.
You may also consider using the Word object model for working with item bodies. The WordEditor property of the Inspector class returns an instance of the Document class which represents the message body. See Chapter 17: Working with Item Bodies for more information.

Resolving incidents (closing cases) in CRM4 through webservices?

I'm trying to resolve/close Dynamics CRM4 cases/incidents through webservices.
A single SetStateIncidentRequest is not enough and returns a Server was unable to process request error message. I think it has something to do with active workflows that trigger on case's attribute changes. I don't know if there's anything else preventing the request to work.
Since it is possible to close those cases through the GUI, I guess there's a "correct" set of steps to follow in order to achieve it through CrmService; unfortunately, I've been googleing it for a while without finding what I want. Could anybody help me, please?
To resolve a case in CRM (in VB.NET), I do the following:
Try
Dim activity As New incidentresolution
Dim closeRequest As New CloseIncidentRequest
Dim closeResponse As New CloseIncidentResponse
Dim strErrors As String = String.Empty()
activity.incidentid = New Lookup
activity.incidentid.type = EntityName.incident.ToString
activity.incidentid.Value = //[GUID OF INCIDENT]
activity.ownerid = New Owner
activity.ownerid.type = EntityName.systemuser.ToString
activity.ownerid.Value = //[GUID OF USER PERFORMING ACTION]
activity.statecode = New IncidentResolutionStateInfo
activity.statecode.Value = 1 //Resolved
activity.statuscode = New Status
activity.statuscode.Value = 5 //Problem Solved
closeRequest.IncidentResolution = activity
closeRequest.Status = 5 //Problem Solved
// IF REQUIRED:
activity.timespent = New CrmNumber
activity.timespent.Value = //[INTEGER REPRESENTING No. OF MIN SPENT ON CASE]
closeResponse = objCrm.Execute(closeRequest)
Catch ex As System.Web.Services.Protocols.SoapException
Dim root As XmlElement = ex.Detail
strErrors = strErrors & vbCrLf & vbCrLf & root.ChildNodes(0).ChildNodes(3).InnerText
Return False
End Try
Here's a tip - catch the SoapException and examine the Detail.OuterXML property and you will get a more detailed error message. It's possible you're not building your request correctly.
Indeed, I didn't know that there exists a CloseIncidentRequest class to use with the CrmService.Execute() method. Most probably the SetStateIncidentRequeset won't work because it's expected that incident resolutions are created that way. Pity that names for classes and actions aren't used consistently (case/incident, resolution/closing)...