How to populate a Treeview with multilevel interconnected refs docs - list

I can't find where I'm going wrong to make the structuring for the levels.
As the attached image is made with a file below it opens until the end. (file basically has single cascade)
The image on the right, on the other hand, contains a level above that has files contained in 3 different levels..
I believe I'm going around a lot to be able to structure according to the files.
structure
Public Class Form1
Public list As New List(Of Linha)
Public Lid As Integer = 0
Dim iPathDoc As String
Private MainSub()
Dim strDocName As String
strDocName = oApprenticeApp.FileManager.GetFullDocumentName(txtFileName.Text, 'Master')
oApprenticeServerDoc = oApprenticeApp.Open(strDocName)
iPathDoc = Microsoft.VisualBasic.Left(oApprenticeServerDoc.FullFileName, InStrRev(oApprenticeServerDoc.FullFileName, '\'))
BuildTreeView()
'Build child nodes
SubNivel()
End Sub
Sub SubNivel()
Dim Final As Boolean = False
'run while finish all list,
'bug ( some times where add a new item at list, its not include on final.. so list is not in sort(how create)
If list.Count <> 0 Then
Do While Final = False
For n = 0 To list.Count - 1
'search each line from list if there reg=false
If list(n).reg = False Then
'if false put = False
Final = False
'if false open
BuildTreeViewRef(list(n).pai, list(n).filho)
Else
'case the item = True
Final = True
End If
Next
Loop
End If
End Sub
Private Sub BuildTreeView()
'set main node
Dim conj As TreeNode = TreeView1.Nodes.Add(oApprenticeServerDoc.FullFileName, oApprenticeServerDoc.DisplayName)
Dim oRefFileDesc As ReferencedFileDescriptor
For Each oRefFileDesc In oApprenticeServerDoc.ReferencedFileDescriptors
If oRefFileDesc.DocumentType = Inventor.DocumentTypeEnum.kAssemblyDocumentObject Then
conj.Nodes.Add(oRefFileDesc.FullFileName, oRefFileDesc.DisplayName, 0, 0)
'add on list each new assy
'creates in order to list = Lid
Lid = Lid + 1
list.Add(New Linha(Lid, oApprenticeServerDoc.FullFileName, oRefFileDesc.FullFileName, False))
Else
conj.Nodes.Add(oRefFileDesc.FullFileName, oRefFileDesc.DisplayName, 1, 1)
End If
Next
End Sub
Private Sub BuildTreeViewRef(Painode As String, refDocName As String)
'open refdoc and local
Dim oRefDoc As String
oRefDoc = oApprenticeApp.FileManager.GetFullDocumentName(refDocName, 'Master')
Dim oAssyDoc As Inventor.ApprenticeServerDocument
oAssyDoc = oApprenticeApp.Open(refDocName)
'set node where include the refDocname, = painode
Dim Root() As TreeNode
Root = TreeView1.Nodes.Find(Painode, True) 'TreeView1.SelectedNode
Dim SubCj() As TreeNode
'check all roots from pai
'If Root.Length > 1 Then
For i = 0 To Root.Length - 1
SubCj = Root(i).Nodes.Find(refDocName, True) 'TreeView1.SelectedNode
Dim oRefFileDesc As ReferencedFileDescriptor
For Each oRefFileDesc In oAssyDoc.ReferencedFileDescriptors
If oRefFileDesc.DocumentType = Inventor.DocumentTypeEnum.kAssemblyDocumentObject Then
SubCj(0).Nodes.Add(oRefFileDesc.FullFileName, oRefFileDesc.DisplayName, 0, 0)
Lid = Lid + 1
list.Add(New Linha(Lid, refDocName, oRefFileDesc.FullFileName, False))
Else
SubCj(0).Nodes.Add(oRefFileDesc.FullFileName, oRefFileDesc.DisplayName, 1, 1)
End If
Next
Next
'check if really the item goes to treeview
For n = 0 To list.Count - 1
If list(n).pai = Painode And list(n).filho = refDocName Then
list(n).reg = True
End If
Next
End Sub
Public Class Linha
Public Property Id() As Integer
Public Property pai() As String
Public Property filho() As String
Public Property reg As Boolean
Public Sub New(ByVal _id As Integer, ByVal _pai As String, ByVal _filho As String, ByVal _reg As Boolean)
Me.Id = _id
Me.pai = _pai
Me.filho = _filho
Me.reg = _reg
End Sub
End Class

Related

Create hierarchy from recordset

I have the following problem:
I have to sort the data of a recordset with a hierarchy.
This is the data as it comes from the database.
You see there are two columns, POS and PARENT.
These values must be related to each other.
If PARENT is 0, then the value in the new sort simply gets a consecutive number. In this case 1-3.
The other values each get a new consecutive number, based on the parent.
I'm pretty sure I could solve this problem in C#, but in this case VB6 is mandatory. Unfortunately I have extreme problems solving the problem with VB6.
This looks like a linked list exercise. You can create a clsListItem class that has a FirstChild object and a NextItem object:
Public Position As Integer
Public Hierarchy As String
Public FirstChild As clsListItem
Public NextItem As clsListItem
As you go down the list, you create a new object and look for its parent. You then check if the FirstChild of the parent exists or not. If it doesn't, you Set the object as the FirstChild, otherwise you navigate through children objects using NextItem until NextItem is Nothing. You then Set the object as NextItem:
Public Sub Sort(ByVal p_sList As String)
Dim arrLines
Dim arrFields
Dim iCounter As Integer
Dim objItem As clsListItem
Dim objParent As clsListItem
Dim objChild As clsListItem
Dim iPosition As Integer
Dim iParent As Integer
Dim iParentIndex As Integer
Dim iChildIndex As Integer
' Split values into lines
arrLines = Split(p_sList, vbCrLf)
' Initialize Parent Index
iParentIndex = 1
For iCounter = 1 To UBound(arrLines) + 1
arrFields = Split(arrLines(iCounter - 1), ",")
iPosition = arrFields(0)
iParent = arrFields(1)
' Get Item
Set objItem = GetItem(iPosition)
If iParent = 0 Then
' This is a top-level item
objItem.Hierarchy = iParentIndex
iParentIndex = iParentIndex + 1
Else
' Get Parent
Set objParent = GetItem(iParent)
' Initialize Child Index
iChildIndex = 1
If objParent.FirstChild Is Nothing Then
' We are the first child
Set objParent.FirstChild = objItem
Else
' Find last child
Set objChild = objParent.FirstChild
iChildIndex = iChildIndex + 1
Do While Not objChild.NextItem Is Nothing
Set objChild = objChild.NextItem
iChildIndex = iChildIndex + 1
Loop
Set objChild.NextItem = objItem
End If
objItem.Hierarchy = objParent.Hierarchy & "." & iChildIndex
End If
Next
Dim sMessage As String
For iCounter = 1 To colListItems.Count
Set objItem = colListItems.item(iCounter)
With objItem
sMessage = sMessage & .Position & ": " & .Hierarchy & vbCrLf
End With
Next
MsgBox sMessage
End Sub
That should organize all your data into objects with the desired hierarchy.
Helper function to Get/Create items:
Public Function GetItem(ByVal p_iPosition As Integer) As clsListItem
Dim objItem As clsListItem
On Error GoTo ItemNotFound
Set objItem = colListItems.item("P" & p_iPosition)
GoTo ReturnItem
ItemNotFound:
Set objItem = New clsListItem
objItem.Position = p_iPosition
colListItems.Add objItem, "P" & p_iPosition
ReturnItem:
Set GetItem = objItem
End Function
Finally, the code I used to create the table of values you have (double-check it, could be typo):
Private Function AddPair(ByVal p_sList As String, ByVal p_iPos As Integer, ByVal p_iParent As Integer) As String
Dim sReturn As String
sReturn = p_sList
If sReturn <> "" Then sReturn = sReturn & vbCrLf
sReturn = sReturn & p_iPos & "," & p_iParent
AddPair = sReturn
End Function
and this is the main subroutine:
Private Sub Form_Load()
Dim list As String
list = AddPair(list, 1, 0)
list = AddPair(list, 13, 0)
list = AddPair(list, 16, 0)
list = AddPair(list, 2, 1)
list = AddPair(list, 12, 1)
list = AddPair(list, 3, 2)
list = AddPair(list, 4, 2)
list = AddPair(list, 5, 2)
list = AddPair(list, 6, 2)
list = AddPair(list, 7, 2)
list = AddPair(list, 8, 7)
list = AddPair(list, 11, 7)
list = AddPair(list, 9, 8)
list = AddPair(list, 10, 8)
list = AddPair(list, 14, 13)
list = AddPair(list, 15, 13)
list = AddPair(list, 17, 16)
list = AddPair(list, 18, 16)
Sort (list)
End Sub

How to stop second run of the code to prevent override data regex vba?

The below code will split 1 cell into 3 or 4 column based on a pattern of 6chr,5chr,4chr,5+chr. The below also needs to be available on all open workbooks and work from the user selection.
How to fix a bug that after the first splitting of the cell is done and by mistake you run it again will override the data?
Class Module
Option Explicit
'Rename this Class Module cFabric
Private pStyle As String
Private pFabric As String
Private pColour As String
Private pSize As String
Public Property Get Style() As String
Style = pStyle
End Property
Public Property Let Style(Value As String)
pStyle = Value
End Property
Public Property Get Fabric() As String
Fabric = pFabric
End Property
Public Property Let Fabric(Value As String)
pFabric = UCase(Value)
End Property
Public Property Get Colour() As String
Colour = pColour
End Property
Public Property Let Colour(Value As String)
pColour = Value
End Property
Public Property Get Size() As String
Size = pSize
End Property
Public Property Let Size(Value As String)
pSize = Value
End Property
Regular Module
Option Explicit
Sub Fabrics()
Dim wsSrc As Workbook, wsRes As Workbook
Dim vSrc As Variant, vRes As Variant, rRes As Range
Dim RE As Object, MC As Object
Const sPat As String = "^(.{6})\s*(.{5})\s*(.{4})(?:.*1/(\S+))?"
'Group 1 = style
'Group 2 = fabric
'Group 3 = colour
'Group 4 = size
Dim colF As Collection, cF As cFabric
Dim I As Long
Dim S As String
Dim V As Variant
'Set source and results worksheets and ranges
Set wsSrc = ActiveWorkbook
Set wsRes = ActiveWorkbook
Set rRes = wsRes.Application.Selection
'Read source data into array
vSrc = Application.Selection
'Initialize the Collection object
Set colF = New Collection
'Initialize the Regex Object
Set RE = CreateObject("vbscript.regexp")
With RE
.Global = False
.MultiLine = True
.Pattern = sPat
'Test for single cell
If Not IsArray(vSrc) Then
V = vSrc
ReDim vSrc(1 To 1, 1 To 1)
vSrc(1, 1) = V
End If
'iterate through the list
For I = 1 To UBound(vSrc, 1)
S = vSrc(I, 1)
Set cF = New cFabric
If .test(S) = True Then
Set MC = .Execute(S)
With MC(0)
cF.Style = .submatches(0)
cF.Fabric = .submatches(1)
cF.Colour = .submatches(2)
cF.Size = .submatches(3)
End With
Else
cF.Style = S
End If
colF.Add cF
Next I
End With
'create results array
'Exit if no results
If colF.Count = 0 Then Exit Sub
ReDim vRes(1 To colF.Count, 1 To 4)
'Populate the rest
I = 0
For Each V In colF
I = I + 1
With V
vRes(I, 1) = .Style
vRes(I, 2) = .Fabric
vRes(I, 3) = .Colour
vRes(I, 4) = .Size
End With
Next V
'Write the results
Set rRes = rRes.Resize(UBound(vRes, 1), UBound(vRes, 2))
rRes.Value = vRes
End Sub
Credits for the above goes to #Ron Rosenfeld for the project!
One way to tell if the entry has been previously split is as follows
If the regex.test fails, then
If the results line passes, then the item has been previously split
if not, then it is a blank, or a malformed entry
Note that a lot of this could be avoided if you were not overwriting your original data. I would recommend against overwriting your data both for audit and debugging purposes, but the below should help in case you cannot change that.
You just need to make some small changes in the logic where we checked for the malformed entry originally. As well as reading in the "possible" results array into vSrc so that we have the potentially split data to compare:
Option Explicit
Sub Fabrics()
'assume data is in column A
Dim wsSrc As Worksheet, wsRes As Worksheet
Dim vSrc As Variant, vRes As Variant, rRes As Range
Dim RE As Object, MC As Object
Const sPat As String = "^(.{6})\s*(.{5})\s*(.{4})(?:.*1/(\S+))?"
'Group 1 = style
'Group 2 = fabric
'Group 3 = colour
'Group 4 = size
Dim colF As Collection, cF As cFabric
Dim I As Long
Dim S As String
Dim V As Variant
'Set source and results worksheets and ranges
Set wsSrc = ActiveSheet
Set wsRes = ActiveSheet
Set rRes = Selection
'Read source data into array
vSrc = Selection.Resize(columnsize:=4)
'Initialize the Collection object
Set colF = New Collection
'Initialize the Regex Object
Set RE = CreateObject("vbscript.regexp")
With RE
.Global = False
.MultiLine = True
.Pattern = sPat
'iterate through the list
'Test for single cell
If Not IsArray(vSrc) Then
V = vSrc
ReDim vSrc(1 To 1, 1 To 1)
vSrc(1, 1) = V
End If
For I = 1 To UBound(vSrc, 1)
S = vSrc(I, 1)
Set cF = New cFabric
If .test(S) = True Then
Set MC = .Execute(S)
With MC(0)
cF.Style = .submatches(0)
cF.Fabric = .submatches(1)
cF.Colour = .submatches(2)
cF.Size = .submatches(3)
End With
ElseIf .test(vSrc(I, 1) & vSrc(I, 2) & vSrc(I, 3)) = False Then
cF.Style = S
Else
cF.Style = vSrc(I, 1)
cF.Fabric = vSrc(I, 2)
cF.Colour = vSrc(I, 3)
cF.Size = vSrc(I, 4)
End If
colF.Add cF
Next I
End With
'create results array
'Exit if not results
If colF.Count = 0 Then Exit Sub
ReDim vRes(1 To colF.Count, 1 To 4)
'Populate
I = 0
For Each V In colF
I = I + 1
With V
vRes(I, 1) = .Style
vRes(I, 2) = .Fabric
vRes(I, 3) = .Colour
vRes(I, 4) = .Size
End With
Next V
'Write the results
Set rRes = rRes.Resize(UBound(vRes, 1), UBound(vRes, 2))
With rRes
.Clear
.NumberFormat = "#"
.Value = vRes
.EntireColumn.AutoFit
End With
End Sub
Disregarding the previous regex/class method,
Option Explicit
Sub Fabrics_part_Deux()
Dim a As Long, b As Long
With Worksheets("Sheet1")
If .AutoFilterMode Then .AutoFilterMode = False
With .Range(.Cells(1, "A"), .Cells(.Rows.Count, "B").End(xlUp).Offset(0, 3))
With .Columns("B")
.Offset(1, 0).Replace what:=Chr(32), replacement:=vbNullString, lookat:=xlPart
End With
.AutoFilter field:=2, Criteria1:="<>"
.AutoFilter field:=3, Criteria1:=""
With .Resize(.Rows.Count - 1, 1).Offset(1, 1)
If CBool(Application.Subtotal(103, .Cells)) Then
With .SpecialCells(xlCellTypeVisible)
For a = 1 To .Areas.Count
With .Areas(a).Cells
.TextToColumns Destination:=.Cells(1), DataType:=xlFixedWidth, _
FieldInfo:=Array(Array(0, 1), Array(6, 1), Array(11, 1), Array(15, 2))
For b = 1 To .Rows.Count
.Cells(b, 2) = UCase$(.Cells(b, 2).Value2)
If CBool(InStr(1, .Cells(b, 4).Value2, Chr(47), vbBinaryCompare)) Then
.Cells(b, 4) = Trim(Split(.Cells(b, 4), Chr(47))(1))
End If
Next b
End With
Next a
End With
End If
End With
End With
If .AutoFilterMode Then .AutoFilterMode = False
End With
End Sub
In your code to output to the spreadsheet, you need to check for empty strings
I = 0
For Each V In colF
I = I + 1
With V
vRes(I, 1) = .Style
If len(.Fabric) > 0 then
vRes(I, 2) = .Fabric
vRes(I, 3) = .Colour
vRes(I, 4) = .Size
End If
End With
Next V

XamDataGrid GroupByEvaluator Date Sorting vb.net

I've been trying to implement some custom grouping with Infragistics xamDataGrid (Infragistics3.Wpf.DataPresenter.v9.1.Express), and pretty much cribbed the entire bit of code from the Infragistics site. I have two different date fields -- Due Date, and Reminder Date -- using GroupByEvaluator. Everything seemed well and good until I tried to add both fields to the GroupByArea.
What happens is this: the nested field groups according to the date of the parent field as opposed to grouping of the parent field. For example, when I drag the "Due Date" (parent) field to the GroupBy, it'll group these records by Due Date into four categories -- Due Next Year, Due This Year, Past Due, and Not Set. Perfect. But when I drag the "Reminder Date" field (nested) to the GroupBy, I'll find multiple labels of the same "Reminder Date" grouping nested under Due Date "Past Due".
I'm a newbie posting to SO, so I can't post an image. Instead, I'll type one out:
Past Due (Due Date)
Not Set (Reminder Date)
This Month (Reminder Date)
Not Set (Reminder Date)
Older (Reminder Date)
Not Set (Reminder Date)
etc....
With each subsequent nested grouping, the earliest Due Date (value of the parent grouping) is equal to or greater than the greatest Due Date of the previous grouping. It appears as though the "Past Due" collection is sorted by Due Date asc, and it's iterating through each record and creating a new nested group whenever there is a change in the nested label. So after 5 groupByRecords are given the label of "This Month", when the next "Not Set" groupByRecord pops up a new nested label is created instead of continuing to populate the existing one.
I'm having a related issue with sorting, which I suspect is what this entire issue hinges on. If the grid has been sorted according to Due Date, all of the sort by functionality of the other fields are constrained by the Due Dates. For example, sorting by client name will not sort all client name records into ascending or descending. Instead, it will sort, but it sort by Due Date first, and then Name.
Sorry I can't attach an image. Hopefully I explained the issue okay.
Thanks in advance! Code below:
Imports System.Collections.ObjectModel
Imports Infragistics.Windows.DataPresenter
Imports System.Windows
Imports System.Windows.Controls
Partial Public Class ManageEntities
Public Sub New()
' This call is required by the designer.
InitializeComponent()
' Add any initialization after the InitializeComponent() call.
Me.InitializeGroupByGrid()
End Sub
#Region "CustomGrouping"
'http://help.infragistics.com/Help/Doc/WPF/2012.2/CLR4.0/html/InfragisticsWPF4.DataPresenter.v12.2~Infragistics.Windows.DataPresenter.IGroupByEvaluator.html
Private Sub InitializeGroupByGrid()
For Each f In Me.SelectorGrid.FieldLayouts(0).Fields
If f.Name = "Form1DueDate" OrElse f.Name = "Form1LastReminderDate" Then
f.Settings.GroupByEvaluator = New CustomDateTimeEvaluator
' group by the data field
Dim fsd As FieldSortDescription = New FieldSortDescription()
fsd.Field = f
fsd.Direction = System.ComponentModel.ListSortDirection.Descending
Me.SelectorGrid.FieldLayouts(0).SortedFields.Add(fsd)
End If
Next
End Sub
#End Region
End Class
#Region "CustomDateTimeEvaluator"
'//20150918 - From infragistics: http://help.infragistics.com/Help/Doc/WPF/2013.1/CLR4.0/html/InfragisticsWPF4.DataPresenter.v13.1~Infragistics.Windows.DataPresenter.IGroupByEvaluator.html
Friend Class CustomDateTimeEvaluator
Implements IGroupByEvaluator
Private Const NotSet As String = "Not Set"
Private Const PastDue As String = "Past Due"
Private Const DueThisYear As String = "Due This Year"
Private Const DueNextYear As String = "Due Next Year"
Private Const RemindThisMonth As String = "This Month"
Private Const RemindLastMonth As String = "Last Month"
Private Const Older As String = "Older"
Dim targetDate As DateTime = Nothing
Public Function DoesGroupContainRecord(ByVal groupByRecord As GroupByRecord, ByVal record As DataRecord) As Boolean Implements IGroupByEvaluator.DoesGroupContainRecord
Dim cellValue As Object = record.GetCellValue(groupByRecord.GroupByField)
Dim desc As String = groupByRecord.Description
' handle null values specially
If cellValue Is Nothing Or TypeOf cellValue Is DBNull Then
Return desc = NotSet
End If
' if the value is not a date time, just group them together
If TypeOf cellValue Is DateTime = False Then
Return True
End If
Return desc = GetDateLabel(CType(cellValue, DateTime), groupByRecord.GroupByField.Name)
End Function
Public Function GetGroupByValue(ByVal groupByRecord As GroupByRecord, ByVal record As DataRecord) As Object Implements IGroupByEvaluator.GetGroupByValue
Dim cellValue As Object = record.GetCellValue(groupByRecord.GroupByField)
Dim desc As String = String.Empty
Dim targetDate As DateTime = DateTime.MinValue
If cellValue Is Nothing Or TypeOf cellValue Is DBNull Then
desc = NotSet
ElseIf TypeOf cellValue Is DateTime Then
targetDate = CType(cellValue, DateTime)
desc = GetDateLabel(targetDate, groupByRecord.GroupByField.Name)
End If
groupByRecord.Description = desc
Return targetDate
End Function
Public ReadOnly Property SortComparer() As System.Collections.IComparer Implements IGroupByEvaluator.SortComparer
Get
Return Nothing
End Get
End Property
Private Function GetDateLabel(ByVal dt As DateTime, ByVal fldName As String) As String
Dim d As String = NotSet
Dim comparison As Integer = Nothing
Dim currentYear As Integer = DatePart(DateInterval.Year, Now)
'//If no date, return NotSet
If dt.Ticks = 0 Then
Return d
End If
'//Group by fieldname name
If fldName.ToLower = "form1duedate" Then
'//Past Due includes any records where the Form 1 Due Date is less than July 1st of the current year
Dim cDDate As New DateTime(currentYear, 7, 1)
comparison = dt.Date.CompareTo(cDDate.Date)
If comparison = 0 Then
d = DueThisYear
ElseIf comparison < 0 Then
d = PastDue
ElseIf comparison > 0 Then
d = DueNextYear
Else
d = NotSet
End If
ElseIf fldName.ToLower = "form1lastreminderdate" Then
Dim currentMonth As Integer = DatePart(DateInterval.Month, Now)
Dim olderThanDate As New DateTime(currentYear, currentMonth - 1, 1)
If dt.Date.Year = currentYear AndAlso dt.Date.Month = currentMonth Then
d = RemindThisMonth
ElseIf dt.Date.Year = currentYear AndAlso dt.Date.Month = currentMonth - 1 Then
d = RemindLastMonth
ElseIf dt.Date < olderThanDate Then
d = Older
Else
d = NotSet
End If
End If
Return d
End Function
End Class
#End Region

How do I create a list in cells choosing from a combobox and selecting a button using VBA?

I have a combobox filled with values. I want to select a value in the combo box and click the "Add" button to place this value into the some cells below. I can add one item to my list using the following code, but I want to be able to add multiple items. I feel that I am very close, I just need a few tweaks!
Private Sub CommandButtonAddItem_Click()
Dim ws As Worksheet
Dim box As ComboBox
Dim food As String
Dim num As Integer
num = 19
Set ws = Worksheets("sheet1")
Set box = ws.OLEObjects("ComboBox1").Object
food = box.Value
Worksheets("sheet1").Cells(num, 1) = food
If Worksheets("sheet1").Cells(num, 1) = " " Then
Worksheets("sheet1").Cells(num, 1) = food
num = num + 1
End If
End Sub
Try THIS!
If the "default" cell is already occupied, it'll keep going down untill it finds one that's not empty, to then put the value in that cell.
Private Sub CommandButtonAddItem_Click()
Dim ws As Worksheet
Dim box As ComboBox
Dim food As String
Dim num As Integer
num = 19
Set ws = Worksheets("sheet1")
Set box = ws.OLEObjects("ComboBox1").Object
food = box.Value
While Worksheets("sheet1").Cells(num, 1) <> ""
num = num + 1
Wend
Worksheets("sheet1").Cells(num, 1) = food
End If
End Sub

Find index of string in large file performance

I have a "container" containing data. The size is +- 100MB.
In the container there a several "dataids's" that mark the begin of something.
Now I need to get an index for an given dataid. (dataid for example: '4CFE7197-0029-006B-1AD4-000000000012')
I have tried several approaches. But at this moment "ReadAllBytes" is the most performant.
ReadAll -> average of 0.6 seconds
Using oReader As New BinaryReader(File.Open(sContainerPath, FileMode.Open, FileAccess.Read))
Dim iLength As Integer = CInt(oReader.BaseStream.Length)
Dim oValue As Byte() = Nothing
oValue = oReader.ReadBytes(iLength)
Dim enc As New System.Text.ASCIIEncoding
Dim sFileContent As String = enc.GetString(oValue)
Dim r As Regex = New Regex(sDataId)
Dim lPosArcID As Integer = r.Match(sFileContent).Index
If lPosArcID > 0 Then
Return lPosArcID
End If
End Using
ReadByteByByte -> average of 1.4 seconds
Using oReader As BinaryReader = New BinaryReader(File.Open(sContainerPath, FileMode.Open, FileAccess.Read))
Dim valueSearch As StringSearch = New StringSearch(sDataId)
Dim readByte As Byte
While (InlineAssignHelper(readByte, oReader.ReadByte()) >= 0)
index += 1
If valueSearch.Found(readByte) Then
Return index - iDataIdLength
End If
End While
End Using
Public Class StringSearch
Private ReadOnly oValue() As Byte
Private iValueIndex As Integer = -1
Public Sub New(value As String)
Dim oEncoding As New System.Text.ASCIIEncoding
Me.oValue = oEncoding.GetBytes(value)
End Sub
Public Function Found(oNextByte As Byte) As Boolean
If oValue(iValueIndex + 1) = oNextByte Then
iValueIndex += 1
If iValueIndex + 1 = oValue.Count Then Return True
Else
iValueIndex = -1
End If
Return False
End Function
End Class
Public Function InlineAssignHelper(Of T)(ByRef target As T, ByVal value As T) As T
target = value
Return value
End Function
I find it hard to believe that there is no faster way.
0.6 seconds for a 100MB file is not an acceptable time.
An other approach that I tried, is to split in chuncks of X bytes (100, 1000, ..). But was alot slower.
Any help on an approach I can try?