How to get a constructor for a Public class to run - vb.net

I have a Public class with a Public Shared Dictionary in vb.net. The constructor does not seem to be running. I have a breakpoint in the constructor which does not break. Also when I make a database update, the new values do not show up in the dictionary.
Public Class SkywalkerPolicy
Public Shared CustomPolicies As Dictionary(Of String, String)
Shared Sub New()
CustomPolicies = New Dictionary(Of String, String)
Dim bvin As String = String.Empty
Dim title As String = String.Empty
Dim poldescr As String = String.Empty
Dim dtResult As New DataTable("Result")
dtResult.Locale = System.Globalization.CultureInfo.InvariantCulture
Dim request As New DataRequest
request.Command = "sky_PolicyDictionary_s"
request.CommandType = CommandType.StoredProcedure
request.Transactional = False
Dim result As DataSet
result = SqlDataHelper.ExecuteDataSet(request)
If Not result Is Nothing Then
If result.Tables.Count() > 0 Then
dtResult = result.Tables(0)
For Each row In dtResult.AsEnumerable
bvin = row.Item(1)
title = row.Item(0)
poldescr = row.Item(2)
If CustomPolicies.ContainsKey(title) Then
CustomPolicies(title) += poldescr
Else
CustomPolicies.Add(title, poldescr)
End If
Next
End If
End If
End Sub
End Class
When I access the dictionary, any changes I've made to the data do not show up.
Dim pol As String = SkywalkerPolicy.CustomPolicies("Orders and Shipping Details")
Does anyone have any suggestions as to how I can get the constructor to work?
Or should I have an additional Sub which duplicates initializing the dictionary before I use it?
Thanks

I have a workaround with an Update routine which I call just before accessing the dictionary. But I am still unclear why I can't step through the constructor. So if anyone can answer the original question, I would appreciate an update. Thank you.
Public Class SkywalkerPolicy
Public Shared CustomPolicies As Dictionary(Of String, String)
Shared Sub New()
CustomPolicies = New Dictionary(Of String, String)
Dim bvin As String = String.Empty
Dim title As String = String.Empty
Dim poldescr As String = String.Empty
Dim dtResult As New DataTable("Result")
dtResult.Locale = System.Globalization.CultureInfo.InvariantCulture
Dim request As New DataRequest
request.Command = "sky_PolicyDictionary_s"
request.CommandType = CommandType.StoredProcedure
request.Transactional = False
Dim result As DataSet
result = SqlDataHelper.ExecuteDataSet(request)
If Not result Is Nothing Then
If result.Tables.Count() > 0 Then
dtResult = result.Tables(0)
For Each row In dtResult.AsEnumerable
bvin = row.Item(1)
title = row.Item(0)
poldescr = row.Item(2)
If CustomPolicies.ContainsKey(title) Then
CustomPolicies(title) += poldescr
Else
CustomPolicies.Add(title, poldescr)
End If
Next
End If
End If
End Sub
Public Shared Sub UpdateDictionary()
CustomPolicies.Clear()
Dim bvin As String = String.Empty
Dim title As String = String.Empty
Dim poldescr As String = String.Empty
Dim dtResult As New DataTable("Result")
dtResult.Locale = System.Globalization.CultureInfo.InvariantCulture
Dim request As New DataRequest
request.Command = "sky_PolicyDictionary_s"
request.CommandType = CommandType.StoredProcedure
request.Transactional = False
Dim result As DataSet
result = SqlDataHelper.ExecuteDataSet(request)
If Not result Is Nothing Then
If result.Tables.Count() > 0 Then
dtResult = result.Tables(0)
For Each row In dtResult.AsEnumerable
bvin = row.Item(1)
title = row.Item(0)
poldescr = row.Item(2)
If CustomPolicies.ContainsKey(title) Then
CustomPolicies(title) += poldescr
Else
CustomPolicies.Add(title, poldescr)
End If
Next
End If
End If
End Sub
End Class

Related

OpenXML Adding Notes and Threaded Comments

I'm posting this to help others that may be going through the struggle I went through when trying to add simple notes or threaded comments to an excel spreadsheet using the DocumentFormat.OpenXML library using VB.Net.
I've added my own answer.
Imports System.Text
Imports DocumentFormat.OpenXml
Imports DocumentFormat.OpenXml.Packaging
Imports DocumentFormat.OpenXml.Spreadsheet
Imports System.Runtime.CompilerServices
Imports System.Xml
Imports System.IO
Imports System.Text.RegularExpressions
Imports DocumentFormat.OpenXml.Office2019.Excel.ThreadedComments
Public Class ExcelDocInfo
Public Property WBPart As WorkbookPart = Nothing
Public Property WSPart As WorksheetPart = Nothing
Public Property SData As SheetData = Nothing
End Class
Public Class CellReferenceIndexes
Public ColumnIndex As Integer? = Nothing
Public RowIndex As Integer? = Nothing
Public Sub New()
End Sub
End Class
Public Class OpenXML
Public Shared Function GetThreadedCommentVMLShapeXML(CellReference As String, CommentCount As Integer)
Dim commentVmlXml As String = String.Empty
commentVmlXml = <![CDATA[
<v:shape id="[ShapeID]" type="#_x0000_t202" style='position:absolute; margin-left:59.25pt;margin-top:1.5pt;width:108pt;height:59.25pt;z-index:1; visibility:hidden' fillcolor="infoBackground [80]" strokecolor="none [81]" o:insetmode="auto">
<v:fill color2="infoBackground [80]"/>
<v:shadow color="none [81]" obscured="t"/>
<v:path o:connecttype="none"/>
<v:textbox style='mso-direction-alt:auto'>
<div style='text-align:left'></div>
</v:textbox>
<x:ClientData ObjectType="Note">
<x:MoveWithCells/>
<x:SizeWithCells/>
<x:Anchor>[CoordinatesForVMLCommentShape]</x:Anchor>
<x:AutoFill>False</x:AutoFill>
<x:Row>[RowIndex]</x:Row>
<x:Column>[ColumnIndex]</x:Column>
</x:ClientData>
</v:shape>
]]>.Value.Trim()
Dim ShapeId As String = "_x0000_s" & (1109 + CommentCount + 1).ToString()
commentVmlXml = commentVmlXml.Replace("[ShapeID]", ShapeId)
commentVmlXml = commentVmlXml.Replace("[CoordinatesForVMLCommentShape]", GetAnchorCoordinatesForVMLCommentShape(CellReference))
commentVmlXml = commentVmlXml.Replace("[RowIndex]", (GetIndexesFromCellReference(CellReference).RowIndex - 1).ToString())
commentVmlXml = commentVmlXml.Replace("[ColumnIndex]", (GetIndexesFromCellReference(CellReference).ColumnIndex - 1).ToString())
Return commentVmlXml
End Function
Public Shared Function GetNoteVMLShapeXML(CellReference As String, CommentCount As Integer)
Dim commentVmlXml As String = String.Empty
commentVmlXml = <![CDATA[
<v:shape id="[ShapeID]" type="#_x0000_t202" style='position:absolute; margin-left:59.25pt; margin-top:1.5pt; width:108pt; height:59.25pt; z-index:1; visibility:hidden' fillcolor="#ffffe1" o:insetmode="auto">
<v:fill color2="#ffffe1" />
<v:shadow on="t" color="black" obscured="t" />
<v:path o:connecttype="none" />
<v:textbox style='mso-fit-shape-to-text:true'>
<div style='text-align:left'></div>
</v:textbox>
<x:ClientData ObjectType="Note">
<x:MoveWithCells />
<x:SizeWithCells />
<x:Anchor>[CoordinatesForVMLCommentShape]</x:Anchor>
<x:AutoFill>False</x:AutoFill>
<x:Row>[RowIndex]</x:Row>
<x:Column>[ColumnIndex]</x:Column>
</x:ClientData>
</v:shape>
]]>.Value.Trim()
Dim ShapeId As String = "_x0000_s" & (1109 + CommentCount + 1).ToString()
commentVmlXml = commentVmlXml.Replace("[ShapeID]", ShapeId)
commentVmlXml = commentVmlXml.Replace("[CoordinatesForVMLCommentShape]", GetAnchorCoordinatesForVMLCommentShape(CellReference))
commentVmlXml = commentVmlXml.Replace("[RowIndex]", (GetIndexesFromCellReference(CellReference).RowIndex - 1).ToString())
commentVmlXml = commentVmlXml.Replace("[ColumnIndex]", (GetIndexesFromCellReference(CellReference).ColumnIndex - 1).ToString())
Return commentVmlXml
End Function
Public Shared Function GetAnchorCoordinatesForVMLCommentShape(CellReference As String) As String
Dim coordinates As String = String.Empty
Dim startingRow As Integer = 0
Dim startingColumn As Integer = GetIndexesFromCellReference(CellReference).ColumnIndex - 1
'From upper right coordinate of a rectangle
'[0] Left column
'[1] Left column offset
'[2] Left row
'[3] Left row offset
'To bottom right coordinate of a rectangle
'[4] Right column
'[5] Right column offset
'[6] Right row
'[7] Right row offset
Dim coordList As List(Of Integer) = {0, 0, 0, 0, 0, 0, 0, 0}.ToList()
If Integer.TryParse(GetIndexesFromCellReference(CellReference).RowIndex, startingRow) Then
startingRow -= 1
coordList(0) = startingColumn + 1
coordList(1) = 15
coordList(2) = startingRow
coordList(4) = startingColumn + 3
coordList(5) = 15
coordList(6) = startingRow + 3
If startingRow = 0 Then
coordList(3) = 2
coordList(7) = 16
Else
coordList(3) = 10
coordList(7) = 4
End If
coordinates = String.Join(",", coordList.ConvertAll(Of String)(Function(X) X.ToString()).ToArray())
End If
Return coordinates
End Function
Public Shared Function GetIndexesFromCellReference(CellReference As String) As CellReferenceIndexes
Dim CellReferenceInfo As New CellReferenceIndexes
Dim ColRef As String = ""
For Each C As Char In CellReference
If Not IsNumeric(C) Then
ColRef &= C
Else
Exit For
End If
Next
ColRef = ColRef.ToUpper()
CellReferenceInfo.RowIndex = Strings.Right(CellReference, CellReference.Length - ColRef.Length)
Dim ColIndex As Integer = 0
For Idx As Integer = 0 To ColRef.Length - 1
ColIndex *= 26
Dim charA As Integer = Asc("A")
Dim charColLetter As Integer = Asc(ColRef(Idx))
ColIndex += (charColLetter - charA) + 1
Next
CellReferenceInfo.ColumnIndex = ColIndex
Return CellReferenceInfo
End Function
Public Shared Sub AddNote(DocInfo As ExcelDocInfo, XCell As Cell, XAuthor As String, Comment As String, Optional XFontName As String = "Tahoma", Optional FontSize As Double = 11, Optional FontBold As Boolean = False, Optional FontItalic As Boolean = False, Optional TextColor As System.Drawing.Color = Nothing, Optional HighlightColor As System.Drawing.Color = Nothing)
If DocInfo Is Nothing Then
Exit Sub
End If
If XCell Is Nothing Then
Exit Sub
End If
If String.IsNullOrEmpty(XAuthor) Then
Exit Sub
End If
If String.IsNullOrEmpty(Comment) Then
Exit Sub
End If
If TextColor = Nothing Then TextColor = System.Drawing.Color.Black
Dim CommentsPart As WorksheetCommentsPart = Nothing
If DocInfo.WSPart.WorksheetCommentsPart Is Nothing Then
CommentsPart = DocInfo.WSPart.AddNewPart(Of WorksheetCommentsPart)
Else
CommentsPart = DocInfo.WSPart.WorksheetCommentsPart()
End If
Dim XComments As Comments = CommentsPart.Comments
If XComments Is Nothing Then
XComments = New Comments() With {.MCAttributes = New MarkupCompatibilityAttributes() With {.Ignorable = "xr"}}
XComments.AddNamespaceDeclaration("mc", "http://schemas.openxmlformats.org/markup-compatibility/2006")
XComments.AddNamespaceDeclaration("xr", "http://schemas.microsoft.com/office/spreadsheetml/2014/revision")
CommentsPart.Comments = XComments
End If
Dim XAuthors As Authors = XComments.GetFirstChild(Of Authors)
If XAuthors Is Nothing Then
XAuthors = New Authors()
XComments.Append(XAuthors)
End If
Dim XLAuthor As Author = (From A As Author In XAuthors.ToList() Where A.Text = XAuthor).FirstOrDefault()
If XLAuthor Is Nothing Then
XLAuthor = New Author() With {.Text = XAuthor}
XAuthors.Append(XLAuthor)
End If
Dim AuthorID As UInt32 = Convert.ToUInt32(XAuthors.AsEnumerable.ToList().IndexOf(XLAuthor))
Dim CommList As CommentList = XComments.GetFirstChild(Of CommentList)
If CommList Is Nothing Then
CommList = New CommentList()
XComments.Append(CommList)
End If
Dim XComment As Comment = XComments.CommentList.AppendChild(Of Comment)(New Spreadsheet.Comment() With {
.AuthorID = New UInt32Value(AuthorID),
.Reference = XCell.CellReference,
.ShapeId = New UInt32Value(Convert.ToUInt32(0))
})
Dim XCommentText As New CommentText()
Dim XRun As New Run()
Dim XRunProperties As New RunProperties()
Dim XFontSize As New FontSize() With {.Val = New DoubleValue(Convert.ToDouble(FontSize))}
Dim XColor As New Color() With {.Rgb = New HexBinaryValue With {.Value = System.Drawing.ColorTranslator.ToHtml(System.Drawing.Color.FromArgb(TextColor.ToArgb())).Replace("#", "")}}
Dim XFillColor As Color = Nothing
If HighlightColor <> Nothing Then
XFillColor = New Color() With {.Rgb = New HexBinaryValue With {.Value = System.Drawing.ColorTranslator.ToHtml(System.Drawing.Color.FromArgb(HighlightColor.ToArgb())).Replace("#", "")}}
End If
Dim XRunFont As New RunFont With {.Val = New StringValue(XFontName)}
Dim XRunBold As New Bold() With {.Val = New BooleanValue(FontBold)}
Dim XRunItalic As New Italic() With {.Val = New BooleanValue(FontItalic)}
Dim xRunPropertyCharSet As New RunPropertyCharSet() With {.Val = New Int32Value(Convert.ToInt32(1))}
XRunProperties.Append(XFontSize)
XRunProperties.Append(XColor)
If XFillColor IsNot Nothing Then
XRunProperties.Append(XFillColor)
End If
XRunProperties.Append(XRunFont)
XRunProperties.Append(XRunBold)
XRunProperties.Append(XRunItalic)
XRunProperties.Append(xRunPropertyCharSet)
Dim XText As New Text() With {.Space = SpaceProcessingModeValues.Preserve, .Text = Comment}
XRun.Append(XRunProperties)
XRun.Append(XText)
XCommentText.Append(XRun)
XComment.Append(XCommentText)
Dim DrawingPartList As List(Of VmlDrawingPart) = DocInfo.WSPart.VmlDrawingParts.ToList()
Dim CommentCount As Integer = 0
Dim DrawingPart As VmlDrawingPart = DocInfo.WSPart.GetPartsOfType(Of VmlDrawingPart)().FirstOrDefault()
Dim Writer As XmlTextWriter = Nothing
Dim DrawingPartStream As Stream = Nothing
Dim SR As StreamReader = Nothing
If DrawingPart Is Nothing Then
DrawingPart = DocInfo.WSPart.AddNewPart(Of VmlDrawingPart)()
DrawingPartStream = DrawingPart.GetStream(IO.FileMode.Create)
SR = New StreamReader(DrawingPartStream)
Writer = New XmlTextWriter(DrawingPartStream, Encoding.UTF8)
Dim XMLText As String = <![CDATA[
<xml xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o=\"urn:schemas-microsoft-com:office:office" xmlns:x="urn:schemas-microsoft-com:office:excel">
<o:shapelayout v:ext="edit">
<o:idmap v:ext="edit" data="1" />
</o:shapelayout>
<v:shapetype id="_x0000_t202" coordsize="21600,21600" o:spt="202" path="m,l,21600r21600,l21600,xe">
<v:stroke joinstyle="miter"/>
<v:path gradientshapeok="t" o:connecttype="rect" />
</v:shapetype>
]]>.Value.Trim()
Writer.WriteRaw(XMLText)
Writer.Flush()
DocInfo.WSPart.Worksheet.AddNamespaceDeclaration("xdr", "http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing")
DocInfo.WSPart.Worksheet.AddNamespaceDeclaration("x14", "http://schemas.microsoft.com/office/spreadsheetml/2009/9/main")
Dim PartID As String = DocInfo.WSPart.GetIdOfPart(DrawingPart)
Dim XLegacyDrawing As LegacyDrawing = New LegacyDrawing() With {.Id = PartID}
DocInfo.WSPart.Worksheet.Append(XLegacyDrawing)
Else
DrawingPartStream = DrawingPart.GetStream()
SR = New StreamReader(DrawingPartStream)
Dim ReadText As String = SR.ReadToEnd()
Dim MatchColl As MatchCollection = Nothing
Dim MatchPattern As New Regex("\<v:shape ")
MatchColl = MatchPattern.Matches(ReadText)
CommentCount = MatchColl.Count
MatchColl = Nothing
MatchPattern = Nothing
Writer = New XmlTextWriter(DrawingPartStream, Encoding.UTF8)
End If
Dim commentsVmlXml As String = String.Empty
commentsVmlXml = GetNoteVMLShapeXML(XCell.CellReference.Value, CommentCount)
Writer.WriteRaw(commentsVmlXml)
Writer.Flush()
Writer.Close()
Writer.Dispose()
Writer = Nothing
SR.Close()
SR.Dispose()
DrawingPartStream.Close()
DrawingPartStream.Dispose()
End Sub
Public Shared Sub AddThreadedComment(DocInfo As ExcelDocInfo, XCell As Cell, XAuthor As String, Comment As String)
If DocInfo Is Nothing Then
Exit Sub
End If
If XCell Is Nothing Then
Exit Sub
End If
If String.IsNullOrEmpty(XAuthor) Then
Exit Sub
End If
If String.IsNullOrEmpty(Comment) Then
Exit Sub
End If
Dim CommentsPart As WorksheetCommentsPart = Nothing
If DocInfo.WSPart.WorksheetCommentsPart Is Nothing Then
CommentsPart = DocInfo.WSPart.AddNewPart(Of WorksheetCommentsPart)
Else
CommentsPart = DocInfo.WSPart.WorksheetCommentsPart()
End If
Dim XComments As Comments = CommentsPart.Comments
If XComments Is Nothing Then
XComments = New Comments() With {.MCAttributes = New MarkupCompatibilityAttributes() With {.Ignorable = "xr"}}
XComments.AddNamespaceDeclaration("mc", "http://schemas.openxmlformats.org/markup-compatibility/2006")
XComments.AddNamespaceDeclaration("xr", "http://schemas.microsoft.com/office/spreadsheetml/2014/revision")
CommentsPart.Comments = XComments
End If
Dim PersPart As WorkbookPersonPart = DocInfo.WBPart.GetPartsOfType(Of WorkbookPersonPart).FirstOrDefault()
If PersPart Is Nothing Then
PersPart = DocInfo.WBPart.AddNewPart(Of WorkbookPersonPart)
End If
Dim PersList As PersonList = PersPart.PersonList
If PersList Is Nothing Then
PersList = New PersonList
PersList.AddNamespaceDeclaration("x", "http://schemas.openxmlformats.org/spreadsheetml/2006/main")
PersPart.PersonList = PersList
End If
Dim Pers As Person = (From P As Person In PersList.AsEnumerable() Where P.DisplayName.Value = XAuthor Select P).FirstOrDefault()
If Pers Is Nothing Then
Pers = New Person() With {.DisplayName = New StringValue(XAuthor), .Id = New StringValue("{" & Guid.NewGuid().ToString().ToUpper() & "}"), .UserId = New StringValue(XAuthor), .ProviderId = New StringValue("None")}
PersList.Append(Pers)
End If
Dim XAuthors As Authors = XComments.GetFirstChild(Of Authors)
If XAuthors Is Nothing Then
XAuthors = New Authors()
XComments.Append(XAuthors)
End If
Dim AuthorGUID As String = "{" & Guid.NewGuid().ToString() & "}"
Dim XLAuthor As Author = New Author() With {.Text = "tc=" & AuthorGUID}
XAuthors.Append(XLAuthor)
Dim WSThreadedCommentsPart As WorksheetThreadedCommentsPart = DocInfo.WSPart.WorksheetThreadedCommentsParts.FirstOrDefault()
If WSThreadedCommentsPart Is Nothing Then
WSThreadedCommentsPart = DocInfo.WSPart.AddNewPart(Of WorksheetThreadedCommentsPart)
End If
Dim XThreadedComments As ThreadedComments = WSThreadedCommentsPart.ThreadedComments
If XThreadedComments Is Nothing Then
XThreadedComments = New ThreadedComments()
WSThreadedCommentsPart.ThreadedComments = XThreadedComments
End If
Dim XThreadedComment As ThreadedComment = New ThreadedComment() With {.Ref = New StringValue(XCell.CellReference), .DT = New DateTimeValue(Now().ToUniversalTime()), .PersonId = Pers.Id, .Id = New StringValue(AuthorGUID)}
Dim XThreadedCommentText As New ThreadedCommentText(Comment)
XThreadedComment.Append(XThreadedCommentText)
XThreadedComments.Append(XThreadedComment)
Dim AuthorID As UInt32 = Convert.ToUInt32(XAuthors.ToList().IndexOf(XLAuthor))
Dim CommList As CommentList = XComments.GetFirstChild(Of CommentList)
If CommList Is Nothing Then
CommList = New CommentList()
XComments.Append(CommList)
End If
Dim XComment As Comment = XComments.CommentList.AppendChild(Of Comment)(New Spreadsheet.Comment() With {
.AuthorID = New UInt32Value(AuthorID),
.Reference = XCell.CellReference,
.ShapeId = New UInt32Value(Convert.ToUInt32(0))
})
XComment.SetAttribute(New OpenXmlAttribute("uid", "http://schemas.microsoft.com/office/spreadsheetml/2014/revision", Pers.Id.Value))
Dim Prepend As String = "[Threaded comment]
Your version of Excel allows you to read this threaded comment; however, any edits to it will get removed if the file is opened in a newer version of Excel. Learn more: https://go.microsoft.com/fwlink/?linkid=870924
Comment:
"
Dim XCommentText As New CommentText()
Dim XText As New Text() With {.Text = Prepend & Comment}
XCommentText.Append(XText)
XComment.Append(XCommentText)
Dim DrawingPartList As List(Of VmlDrawingPart) = DocInfo.WSPart.VmlDrawingParts.ToList()
Dim CommentCount As Integer = 0
Dim DrawingPart As VmlDrawingPart = DocInfo.WSPart.GetPartsOfType(Of VmlDrawingPart)().FirstOrDefault()
Dim Writer As XmlTextWriter = Nothing
Dim DrawingPartStream As Stream = Nothing
Dim SR As StreamReader = Nothing
If DrawingPart Is Nothing Then
DrawingPart = DocInfo.WSPart.AddNewPart(Of VmlDrawingPart)()
DrawingPartStream = DrawingPart.GetStream(IO.FileMode.Create)
SR = New StreamReader(DrawingPartStream)
Writer = New XmlTextWriter(DrawingPartStream, Encoding.UTF8)
Dim XMLText As String = <![CDATA[
<xml xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o=\"urn:schemas-microsoft-com:office:office" xmlns:x="urn:schemas-microsoft-com:office:excel">
<o:shapelayout v:ext="edit">
<o:idmap v:ext="edit" data="1" />
</o:shapelayout>
<v:shapetype id="_x0000_t202" coordsize="21600,21600" o:spt="202" path="m,l,21600r21600,l21600,xe">
<v:stroke joinstyle="miter"/>
<v:path gradientshapeok="t" o:connecttype="rect" />
</v:shapetype>
]]>.Value.Trim()
Writer.WriteRaw(XMLText)
Writer.Flush()
DocInfo.WSPart.Worksheet.AddNamespaceDeclaration("xdr", "http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing")
DocInfo.WSPart.Worksheet.AddNamespaceDeclaration("x14", "http://schemas.microsoft.com/office/spreadsheetml/2009/9/main")
Dim PartID As String = DocInfo.WSPart.GetIdOfPart(DrawingPart)
Dim XLegacyDrawing As LegacyDrawing = New LegacyDrawing() With {.Id = PartID}
DocInfo.WSPart.Worksheet.Append(XLegacyDrawing)
Else
DrawingPartStream = DrawingPart.GetStream()
SR = New StreamReader(DrawingPartStream)
Dim ReadText As String = SR.ReadToEnd()
Dim MatchColl As MatchCollection = Nothing
Dim MatchPattern As New Regex("\<v:shape ")
MatchColl = MatchPattern.Matches(ReadText)
CommentCount = MatchColl.Count
MatchColl = Nothing
MatchPattern = Nothing
Writer = New XmlTextWriter(DrawingPartStream, Encoding.UTF8)
End If
Dim commentsVmlXml As String = String.Empty
commentsVmlXml = GetThreadedCommentVMLShapeXML(XCell.CellReference.Value, CommentCount)
Writer.WriteRaw(commentsVmlXml)
Writer.Flush()
Writer.Close()
Writer.Dispose()
Writer = Nothing
SR.Close()
SR.Dispose()
DrawingPartStream.Close()
DrawingPartStream.Dispose()
End Sub
Public Shared Sub FinalizeComments(DocInfo As ExcelDocInfo)
Dim DrawingPart As VmlDrawingPart = DocInfo.WSPart.GetPartsOfType(Of VmlDrawingPart)().FirstOrDefault()
If DrawingPart IsNot Nothing Then
Using DrawingPartStream As Stream = DrawingPart.GetStream()
Using SR As StreamReader = New StreamReader(DrawingPartStream)
Dim ReadText As String = SR.ReadToEnd()
If Not ReadText.ToLower().EndsWith("</xml>") Then
Using Writer As XmlTextWriter = New XmlTextWriter(DrawingPartStream, Encoding.UTF8)
Writer.WriteRaw("</xml>")
Writer.Flush()
Writer.Close()
End Using
End If
SR.Close()
End Using
DrawingPartStream.Close()
End Using
End If
End Sub
Public Shared Function GetCell(ExcelRow As Row, ColumnNumber As Integer) As Cell
Dim WSCell As Cell = Nothing
If (From C As Cell In ExcelRow.Elements(Of Cell) Where C.CellReference.Value = ExcelColToName(ColumnNumber) & ExcelRow.RowIndex.ToString()).Count > 0 Then
WSCell = (From C As Cell In ExcelRow.Elements(Of Cell) Where C.CellReference.Value = ExcelColToName(ColumnNumber) & ExcelRow.RowIndex.ToString()).FirstOrDefault()
Else
WSCell = New Cell() With {.CellReference = ExcelColToName(ColumnNumber) & ExcelRow.RowIndex.ToString()}
ExcelRow.InsertAt(Of Cell)(WSCell, ExcelRow.Elements(Of Cell).Count)
End If
Return WSCell
End Function
Public Shared Function GetRow(SData As SheetData, RowNumber As Integer) As Row
Dim R As Row = Nothing
Dim RIdx As UInt32Value = Convert.ToUInt32(RowNumber)
If SData.Elements(Of Row).Count > 0 Then
R = (From ERow As Row In SData.Elements(Of Row) Where ERow.RowIndex = RIdx).FirstOrDefault()
End If
If R Is Nothing Then
R = New Row() With {.RowIndex = RIdx}
SData.Append(R)
End If
Return R
End Function
End Class
Public Class TestCase
Public Sub RunTest()
'This sample does not dive into the creation of the spreadsheet. This example focuses strictly on notes and threaded comments.
'In a production example, there would be another sub in the OpenXML class that would populate this ExcelDocInfo object.
'Note that this code will fail as the objects within the DocInfo object currently have no reference to actual objects
Dim DocInfo As New ExcelDocInfo
Dim RowIdx As Integer = 1
Dim ColIdx As Integer = 1
Dim XRow As Row = OpenXML.GetRow(DocInfo.SData, RowIdx)
Dim XCell As Cell = OpenXML.GetCell(XRow, ColIdx)
OpenXML.AddThreadedComment(DocInfo, XCell, "Author Name", "Comment Text Goes Here")
OpenXML.FinalizeComments(DocInfo)
End Sub
End Class
Great post - I was going through that struggle. :-)
I had to make the following changes for the code to work in my case.
Without these changes Excel was unable to open the resulting document.
What is still failing is starting off from a ClosedXML generated document that contains old-school notes.
Remove the backslash in 2 locations of xmlns:o=\"urn:schemas-microsoft-com
Add ToUpper here, a GUID needs to be uppercase:
Dim AuthorGUID As String = "{" & Guid.NewGuid().ToString().ToUpper() & "}"
Ensure the x:tableParts element is after the x:legacyDrawing element in the sheet xml
Dim PartID As String = DocInfo.WSPart.GetIdOfPart(DrawingPart)
Dim XLegacyDrawing As LegacyDrawing = New LegacyDrawing() With {.Id = PartID}
Dim tableXMLElement = DocInfo.WSPart.Worksheet.ChildElements().Where(Function(x) x.GetType Is GetType(TableParts)).FirstOrDefault
If tableXMLElement IsNot Nothing Then
tableXMLElement.InsertBeforeSelf(Of OpenXmlElement)(XLegacyDrawing)
Else
DocInfo.WSPart.Worksheet.Append(XLegacyDrawing)
End If

Split Field in a Linq Query

Below is the content of a field name OULocationPath. I need to parse out the OU=location but only the "location". Not the "OU=".
CN=my name,OU=department,OU=location,OU=general area,DC=company,DC=org
Below is the query that I use to populate a grid. I haven't added the field above as of yet.
Public Function GetLocationList() As List(Of Contact)
GetLocationList = mContacts.FindAll(Function(x) x.Company.Contains("CompanyName") = True And x.WorkEmail = Nothing And x.WorkPhone <> "")
End Function
Thank you!
#Andrew Morton and #NetMage,
I was able to get the parse working using the code below:
Public Function GetLocationList() As List(Of Contact)
GetLocationList = Nothing
Dim Answerset = mContacts.FindAll(Function(x) x.Company.Contains("CompanyName") = True AndAlso x.WorkEmail = Nothing AndAlso x.WorkPhone IsNot Nothing)
Dim _GridLocations As New List(Of Contact)
Dim _GridLocation As Contact
_GridLocations.Clear()
For Each l In Answerset
_GridLocation = New Contact
With _GridLocation
.FullName = l.FullName
.WorkPhone = l.WorkPhone
.Extension = l.Extension
Dim s As String = l.OULocationPath
Dim sp As String() = s.Split(New [Char]() {","c, "="c})
Dim first6 As String() = sp.ToList().GetRange(0, 6).ToArray()
.OULocationPath= first6(5)
End With
_GridLocations.Add(_GridLocation)
Next
GetLocationList = _GridLocations
End Function

VB API Result converts decimal numbers

I have a simple API Post like this
<HttpPost>
Public Function testPost() As IEnumerable(Of sp_select)
Dim _tmplist As New List(Of sp_select)
Dim _Content = jsonSerializer.Deserialize(Of myparams)(Request.Content.ReadAsStringAsync().Result)
Dim mandant = _Content.mandant
Using mycon As New dal_globalDataContext
Dim _result = mycon.sp_select(CType(mandant, Decimal)).ToList
If Not _result.Any = False Then
For Each entry In _result
_tmplist.Add(entry)
Next
End If
End Using
Return _tmplist
End Function
All good. But If I parse the result like this:
Public Sub testPost()
Dim client = New System.Net.Http.HttpClient()
client.BaseAddress = New Uri("http://localhost:62068")
client.DefaultRequestHeaders.Accept.Clear()
client.DefaultRequestHeaders.Accept.Add(New System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"))
Dim _datasource As IEnumerable(Of Object) = Nothing
Dim _content = New With {.mandant = 0}
Dim serializer As New JavaScriptSerializer()
Dim arrayJson As String = serializer.Serialize(_content)
Dim responseTask = client.PostAsync("/actionapi/dataSource/testPost/", New StringContent(arrayJson))
responseTask.Wait()
Dim result = responseTask.Result
If result.IsSuccessStatusCode Then
Dim readTask = result.Content.ReadAsAsync(Of IList(Of sp_select))()
readTask.Wait()
_datasource = readTask.Result
Any decimal property of the class has an decimal point. So 1 will be 1.0
Do you know how to prevent this behaviour?

How to return that all threads are finished in a function?

I have this code that starts some threads by iterating through a list of strings and send each one to a Sub which connects to a webservice and waits for a result:
Public Shared Function StartThreading(names As String())
Dim threads As List(Of Thread) = New List(Of Thread)()
For Each name In names
Dim t As Thread = New Thread(New ParameterizedThreadStart(Sub() CallWebService(name)))
threads.Add(t)
Next
For i As Integer = 0 To threads.Count - 1
Dim t = threads(i)
Dim name = names(i)
t.Start(name)
Next
For Each t As Thread In threads
t.Join()
Next
End Function
The Sub for the webservice caller is:
Public Shared Sub CallWebService(inputxml As String)
Dim _url = "http://10.231.58.173:8080/ps/services/ProcessServer?WSDL"
Dim _action = "http://10.231.58.173:8080/ps/services/ProcessServer"
Dim soapEnvelopeXml As XmlDocument = CreateSoapEnvelope(inputxml)
Dim webRequest As HttpWebRequest = CreateWebRequest(_url, _action)
Dim appPath As String = System.AppDomain.CurrentDomain.BaseDirectory
Dim configpath As String = appPath + "\Config.ini"
Dim configdata As IniData = Functii.ReadIniFile(configpath)
Dim outputxmlsave = configdata("PATHS")("OUTPUTXML")
InsertSoapEnvelopeIntoWebRequest(soapEnvelopeXml, webRequest)
Dim asyncResult As IAsyncResult = webRequest.BeginGetResponse(Nothing, Nothing)
asyncResult.AsyncWaitHandle.WaitOne()
Dim soapResult As String
Using webResponse As WebResponse = webRequest.EndGetResponse(asyncResult)
Using rd As StreamReader = New StreamReader(webResponse.GetResponseStream())
soapResult = rd.ReadToEnd()
End Using
File.WriteAllText(outputxmlsave & "\" & "test.xml", soapResult.ToString)
Console.Write(soapResult)
End Using
End Sub
How can I know that all threads are done successfully or not? Is there something I can use to return a True value if they are all done?

VB.Net signedXml "Invalid character in a Base-64 string"

I'm getting an error everytime I try to upload a XML file to an specific server.
It returns "Invalid character in a Base-64 string". Here the code I'm using to sign:
Public Sub Assinar03(ByVal strArqXMLAssinar As String, ByVal strUri As String, ByVal x509Certificado As X509Certificate2, ByVal strArqXMLAssinado As String)
Dim SR As StreamReader = Nothing
SR = File.OpenText(strArqXMLAssinar)
Dim vXMLString As String = SR.ReadToEnd()
SR.Close()
Dim _xnome As String = String.Empty
Dim _serial As String = String.Empty
If x509Certificado IsNot Nothing Then
_xnome = x509Certificado.Subject.ToString()
_serial = x509Certificado.SerialNumber
End If
Dim _X509Cert As New X509Certificate2()
Dim store As New X509Store("MY", StoreLocation.CurrentUser)
store.Open(OpenFlags.[ReadOnly] Or OpenFlags.OpenExistingOnly)
Dim collection As X509Certificate2Collection = DirectCast(store.Certificates, X509Certificate2Collection)
Dim collection1 As X509Certificate2Collection = DirectCast(collection.Find(X509FindType.FindBySerialNumber, _serial, False), X509Certificate2Collection)
If collection1.Count > 0 Then
_X509Cert = Nothing
For i As Integer = 0 To collection1.Count - 1
If DateTime.Now < collection1(i).NotAfter OrElse Not _X509Cert Is Nothing AndAlso _X509Cert.NotAfter < collection1(i).NotAfter Then
_X509Cert = collection1(i)
End If
Next
If _X509Cert Is Nothing Then _X509Cert = collection1(0)
Dim doc As New XmlDocument()
doc.PreserveWhitespace = False
doc.LoadXml(vXMLString)
Dim qtdeRefUri As Integer = doc.GetElementsByTagName(strUri).Count
Dim reference As New Reference()
Dim keyInfo As New KeyInfo()
Dim signedXml As New SignedXml(doc)
signedXml.SigningKey = _X509Cert.PrivateKey
Dim _Uri As XmlAttributeCollection = doc.GetElementsByTagName(strUri).Item(0).Attributes
For Each _atributo As XmlAttribute In _Uri
If _atributo.Name.ToLower.Trim = "Id".ToLower.Trim Then
reference.Uri = "#" + _atributo.InnerText
End If
Next
If reference.Uri Is Nothing Then reference.Uri = ""
reference.DigestMethod = SignedXml.XmlDsigSHA1Url
'--------------------------------------------------
Dim env As New XmlDsigEnvelopedSignatureTransform()
env.Algorithm = "http://www.w3.org/2000/09/xmldsig#enveloped-signature"
reference.AddTransform(env)
'--------------------------
Dim c14 As New XmlDsigC14NTransform(False)
c14.Algorithm = "http://www.w3.org/TR/2001/REC-xml-c14n-20010315"
reference.AddTransform(c14)
'--------------------------
signedXml.AddReference(reference)
keyInfo.AddClause(New KeyInfoX509Data(_X509Cert))
'--------------------------
signedXml.KeyInfo = keyInfo
signedXml.ComputeSignature()
'--
Dim xmlDigitalSignature As XmlElement = signedXml.GetXml()
doc.DocumentElement.AppendChild(doc.ImportNode(xmlDigitalSignature, True))
XMLDoc = New XmlDocument()
XMLDoc.PreserveWhitespace = False
XMLDoc = doc
Me.vXMLStringAssinado = XMLDoc.OuterXml
'-----------
Dim SW_2 As StreamWriter = File.CreateText(strArqXMLAssinado)
SW_2.Write(Me.vXMLStringAssinado)
SW_2.Close()
'-----------
End If
SR.Close()
End Sub
Is there something else I should add to the code?
The manual tells me to follow the instructions from https://www.w3.org/TR/xmldsig-core/
Turns out it was a line break when saving the document. I set the .PreserveWhitespace property to true before saving the .xml file and not it seems to be working.