Quote Originally Posted by softv View Post
I had always thought that I should try loading large text files in Krool's VBFlexGrid and try but never got time for the same, as other things got up in the priority list. So, is it possible Olaf, with VBFlexGrid too?
Sure... relatively easy to do via the IVBFlexDataSource interface, when you implement it in a little Class like the one below.

Into a Class, named cTextDataSource:

Code:
Option Explicit

Implements IVBFlexDataSource

Private Declare Function MultiByteToWideChar Lib "kernel32" (ByVal codePage As Long, ByVal dwFlags As Long, ByVal lpMultiByteStr As Long, ByVal cchMultiByte As Long, ByVal lpWideCharStr As Long, ByVal cchWideChar As Long) As Long

Private UTF8() As Byte, Offsets() As Long, LineCount As Long, LastLineIdx As Long, Line As String

Public Sub BindToTextFile(FG As VBFlexGrid, FileName As String)
  UTF8 = ReadFileBytes(FileName)
  LineCount = GetLines(UTF8, Offsets)
  LastLineIdx = -1
  
  Set FG.FlexDataSource = Me 'bind this Class (and set a few FG-defaults)
      FG.ColWidth(0) = 1800
      FG.ExtendLastCol = True
      FG.ScrollTrack = True
End Sub

Private Function ReadFileBytes(FileName As String) As Byte()
  Dim FNr As Long: FNr = FreeFile
  On Error GoTo 1
  Open FileName For Binary As FNr
       ReDim ReadFileBytes(LOF(FNr) - 1)
       Get FNr, , ReadFileBytes
1 If Err Then ReadFileBytes = StrConv(Err.Description, vbFromUnicode)
  Close FNr
End Function
 
Private Function GetLines(UTF8() As Byte, Offsets() As Long) As Long
  Dim OffsUB As Long: OffsUB = 1024: ReDim Offsets(OffsUB)
  
  Dim i As Long, j As Long, LF As Byte
  For i = 0 To UBound(UTF8)
    If UTF8(i) = 13 Or UTF8(i) = 10 Then LF = UTF8(i): Exit For
  Next
  For i = 0 To UBound(UTF8)
    If UTF8(i) = LF Then
       If j >= OffsUB Then OffsUB = 1.5 * OffsUB: ReDim Preserve Offsets(OffsUB)
       j = j + 1: Offsets(j) = i
    End If
  Next
  If UTF8(i - 1) <> 13 And UTF8(i - 1) <> 10 Then
     If j >= OffsUB Then OffsUB = 1.5 * OffsUB: ReDim Preserve Offsets(OffsUB)
     j = j + 1: Offsets(j) = i
  End If
  GetLines = j
End Function

Private Function GetLine(ByVal ZeroBasedLineIdx As Long) As String
  Dim Offs As Long: Offs = Offsets(ZeroBasedLineIdx)
            If UTF8(Offs) = 13 Then Offs = Offs + 1
            If UTF8(Offs) = 10 Then Offs = Offs + 1
  Dim BLen As Long: BLen = Offsets(ZeroBasedLineIdx + 1) - Offs
      
  If BLen > 0 Then 'UTF8-to-BSTR conversion, directly from the UTF8-bytearray
     GetLine = Space$(MultiByteToWideChar(65001, 0, VarPtr(UTF8(Offs)), BLen, 0, 0))
     MultiByteToWideChar 65001, 0, VarPtr(UTF8(Offs)), BLen, StrPtr(GetLine), Len(GetLine)
  End If
End Function

'***** Implementation of IVBFlexDataSource *****
Private Function IVBFlexDataSource_GetRecordCount() As Long
  IVBFlexDataSource_GetRecordCount = LineCount
End Function

Private Function IVBFlexDataSource_GetFieldCount() As Long
  IVBFlexDataSource_GetFieldCount = 2
End Function

Private Function IVBFlexDataSource_GetFieldName(ByVal Field As Long) As String
  Select Case Field
    Case 0: IVBFlexDataSource_GetFieldName = "TimeStamp"
    Case 1: IVBFlexDataSource_GetFieldName = "LogInfo"
  End Select
End Function

Private Function IVBFlexDataSource_GetData(ByVal Field As Long, ByVal Record As Long) As String
  If LastLineIdx <> Record Then
     LastLineIdx = Record
     Line = GetLine(Record)
  End If
  Select Case Field
    Case 0: IVBFlexDataSource_GetData = Left$(Line, 19)
    Case 1: IVBFlexDataSource_GetData = Mid$(Line, 21)
  End Select
End Function

Private Sub IVBFlexDataSource_SetData(ByVal Field As Long, ByVal Record As Long, ByVal NewData As String)
End Sub
And this into a Form for testing with one of your own Log- or TextFiles:
(the Form needs an instance of VBFlexgrid1, ... either in version 1.4. or in newest version 1.5)
Code:
Option Explicit

Const FileName = "c:\temp\test3.txt"

Private FlexDS As New cTextDataSource

Private Sub Form_Load()
    VBFlexGrid1.Font.Name = "Arial"
    FlexDS.BindToTextFile VBFlexGrid1, FileName
End Sub
 
Private Sub Form_Resize()
    VBFlexGrid1.Move 0, 0, ScaleWidth, ScaleHeight
End Sub
Since the FlexGrid is normally used for "Multi-Column-Data",
I've artificially created a LogFile with a leading (ISO) Timestamp per Line, to have more than one Column "to split" for the FG.

Used the RC6 for that, with the following snippet:
Code:
  With New_c.StringBuilder
    Dim i As Long, D As Double: D = Now
    For i = 1 To 100000
      D = D + 1 / 86400
      .Add Format$(D, "yyyy\-mm\-dd hh\:nn\:ss")
      .AddNL " Some loooooooooooooooooonger Log-Entry-Line " & i
    Next
    New_c.FSO.WriteByteContent FileName, .ToUTF8
  End With
HTH

Olaf