Most of the properties that were prefixed with 'Get' e.g. .GetColumnName, are written in VB as functions. The most basic of the methods, like
.MoveFirst seem to be working fine but there are many more, and many more properties, that I haven't been able to test yet. The testing I did do
seemed to indicate that some of the entry points probably won't work as expected in the current .Net implementation. I looked at the standard ADO Field properties that appeared
to be supported within Summation/VBScript and created a new Field (nested in Fields class) class for them.
You can create a new Field object and from there access Value and other properties:
VB
sw.DB.MoveFirst()
Dim summary As New sw.DB.Field("Summary")
Dim currsummary As String = summary.Value
summary.Value = currsummary & " new info for summary field"
sw.DB.Update()
sw.DB.Refresh()
currsummary = summary.Value
MessageBox.Show(currsummary)
As an experiment I put a .GetFields into Fields, which will return a typed/Generic List
for the current record:
C#
sw.DB.MoveFirst();
List<sw.DB.Field> flds = sw.DB.Fields.GetFields();
foreach (sw.DB.Field fld in flds)
{
string myField = fld.Name + " " + fld.Value;
}
Often though, as long as read-only data is acceptable and the recordset is not too large, the best approach can be to use .Clone and
.Cull, which will be returning a true ADODB.Recordset. This is especially true in Enterprise, whose
DB object sometimes runs into problems when it comes to reading data. First you will likely need to add a Reference to your project
in order to get access to the ADODB namespace. Then see below for some sample usage:
C#
//Num of displayed fields vs. total num of fields
long fieldCount = sw.DB.Fields.Count;
string delim = "|";
string displayedFields = sw.DB.GetDisplayedCols(delim);
int displayedFieldCount = displayedFields.Split(delim.ToCharArray()).Length;
string displayedVsAllFields = String.Format("Of {0} fields in total, {1}
are in the current display", fieldCount, displayedFieldCount);
int allRecords = 1;
bool hyphenatedDate = false;
ADODB.Recordset displayedRecs = sw.DB.Clone(allRecords, displayedFields, delim, hyphenatedDate);
//which fields in Cloned recordset are of Integer datatype
string displayedIntegerFields = "Fields from current display that are Integer dataype:\r\n";
foreach (ADODB.Field adoField in displayedRecs.Fields)
{
if (adoField.Type == ADODB.DataTypeEnum.adInteger)
{
displayedIntegerFields += adoField.Name + "\r\n";
}
}
//make delimited string of the docids in the Cloned recordset
string docids = "";
displayedRecs.MoveFirst();
for (int i = 1; i <= displayedRecs.RecordCount; i++)
{
docids += displayedRecs.Fields["Docid"].Value + delim;
displayedRecs.MoveNext();
}
DB.Defaults
All properties, all nice and simple.
DBGrid
DBGrid is another complicated object, where it is accessed via an existing View, instead allowing for a direct connection. Implementation may
change down the line but for now DBGrid is an instance class and may be accessed at least three different ways, each displayed below. There isn't yet a Field/Fields sub-class either,
so the only way of accessing the data via the wrapper is to .Clone it first, at which point you would be dealing with a standard, read-only ADODB
recordset.
Create DBGrid object by passing in a viewId integer:
VB
Dim peoplePath As String = Path.Combine(sw.CurrentCase.SharedProfileDir, "People.udl")
Dim viewId As Integer = sw.Views.CreateGrid(peoplePath, "People via CreateGrid")
'give it 10 seconds to fully open
Threading.Thread.Sleep(10000)
Dim peopleGrid As sw.DBGrid = New sw.DBGrid(viewId)
Dim recordCount As Integer = peopleGrid.RecordCount
If you know the currently active View is a DBGrid object:
VB
Dim grid As sw.DBGrid = sw.Views.ActiveView_AsDBGrid()
recordCount = grid.RecordCount
grid.MoveFirst()
grid.AbsolutePosition = recordCount
grid = Nothing
Pass in a View name (of DBGrid type) as a string:
VB
Dim people As sw.DBGrid = New sw.DBGrid("People")
Const markedRecords As Integer = 2
Dim clone As ADODB.Recordset
recordCount = people.RecordCount
people.MoveFirst()
people.MarkRows(1, recordCount - 1)
clone = people.Clone(markedRecords)
clone.MoveFirst()
Dim firstRow As String = "First row in clone:" & vbCrLf
For Each fld As ADODB.Field In clone.Fields
Dim fieldValue As String
If IsDBNull(fld.Value) Then
fieldValue = "(null)"
Else
fieldValue = fld.Value
End If
firstRow = firstRow & fld.Name & vbTab & vbTab & fieldValue & vbCrLf
Next
MessageBox.Show(firstRow)
clone = Nothing
eDocs
Not much available in eDocs and of what is there, not all would appear to work correctly, even with native
Summation application. Below attempts to retrieve the eDocs in the current case and grab the text from the eDoc viewer for the first record
(assumes eDoc view is open and in Text mode):
C#
sw.eDocs.RetrieveAll();
if (sw.DB.RecordCount > 0)
{
sw.DB.MoveFirst();
sw.Views.View eDocView = new sw.Views.View(sw.Views.View.ViewType.eDoc);
object eDocViewObject = eDocView.GetObject;
string eDocText = "Text of first eDoc:\r\n\r\n";
if (eDocViewObject as mshtml.HTMLDocument != null)
{
mshtml.HTMLDocument hDoc = (mshtml.HTMLDocument)eDocViewObject;
eDocText += hDoc.body.innerText;
}
else
{
eDocText += "(failed to retrieve)";
}
}
Img
The Img object is pretty straightforward but has many properties and methods and I've tested relatively few. The below assumes
a PictureBox has been created on an existing VB WinForm. It grabs the pathing info of the current image in Summation and displays.
Clicking PictureBox1 will loop through each page of the image, as long as it is not a true multipage image file. The image is re-saved as a
bitmap, endorsed with the image tag and page number at the top left and the label (Stamp and Label Setup in Summation image viewer) if any, at the bottom left.
PictureBox1 is loaded with the resulting .bmp file:
VB
Private Sub PictureBox1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
Handles PictureBox1.Click
If Not sw.Img.IsCurDocMultipage Then
Dim numPage As Long = sw.Img.NumPages
Dim tempFilePath = Path.Combine(sw.Application.AppProfile, "endorsedImage.bmp")
ApplyLabelToImage(sw.Img.GetNthImgFile(sw.Img.DefDir, sw.Img.ImgFiles, _currPage),
_currPage, tempFilePath)
Me.PictureBox1.ImageLocation = tempFilePath
If _currPage < numPage Then
_currPage = _currPage + 1
Else
_currPage = 1
End If
End If
End Sub
Sub ApplyLabelToImage(ByVal imageFilePath As String, ByVal currPage As Long,
ByVal tempFilePath As String)
Dim singleImageFilePath As String = sw.Img.GetNthImgFile(sw.Img.DefDir, sw.Img.ImgFiles,
_currPage)
If Not File.Exists(singleImageFilePath) Then
singleImageFilePath = Path.Combine(sw.Application.AppDir, "noimage.tif")
End If
Dim newImg As Image = Drawing.Image.FromFile(singleImageFilePath)
Dim newBmp As New Drawing.Bitmap(newImg, PictureBox1.Width, PictureBox1.Height)
Dim g As Drawing.Graphics = Drawing.Graphics.FromImage(newBmp)
Dim myFont As Font = New Font(Me.Font, FontStyle.Bold)
Dim myBrush As New SolidBrush(Color.Red)
Dim docSpecs, docLabel As String
docSpecs = sw.Img.DocName & vbTab & "Page: " & currPage
docLabel = sw.Img.GetDocLabel()
g.DrawString(docSpecs, myFont, myBrush, 10, 10)
g.DrawString(docLabel, myFont, myBrush, 10, Me.PictureBox1.Height - 20)
newBmp.Save(tempFilePath, Drawing.Imaging.ImageFormat.Bmp)
End Sub
Img.OCR
One of the smaller objects, with less than fifteen total properties and methods. First example is in C#, where each of the available parameters for
Img.OCR.OcrImage is being passed in:
C#
string outputFilePath = @"C:\test\output.txt";
bool appendTheText = false;
bool ocrBaseStyle = false;
string tempFilePath = @"C:\test\tempfile.txt";
string imageFile = Path.Combine(sw.Application.AppDir,
@"CaseData\P. FRANC VS. K. MORRIS (version 2.5)\IMAGES\BK000001.tif");
sw.Img.OCR.ImageFile = imageFile;
sw.Img.OCR.OcrImage(imageFile, outputFilePath, appendTheText, ocrBaseStyle, tempFilePath);
while the second illustrates the use of a different overload on Img.OCR.OcrImage, the one that passes in the only parameter
required by the Summation app, for image file path:
VB
sw.Img.OCR.ImageFile = Path.Combine(sw.Application.AppDir,
"CaseData\P. FRANC VS. K. MORRIS (version 2.5)\IMAGES\BK000001.tif")
sw.Img.OCR.OcrImage(sw.Img.OCR.ImageFile)
Either way this particular method results in the OCR UI appearing in the Summation app, where it must be handled somehow.
Notes
Described as very similar to CurrentNote object, where presumably the main difference is that CurrentNote
requires the Note UI be open. This was the first object in which I noticed problems that were due solely to swsom actions, or more accurately, problems that only
manifested themselves in terms of external access. The three Retrieve methods (RetrieveAll,
RetrieveAllOcrBaseNotes, RetrieveAllTranNotes) work fine when run from the Scripting
window within Summation but failed to do anything when called externally, even from a .vbs file. The comments for those three have been updated but the actual methods are still
available - perhaps there is some environmental component involved and they will work correctly for others. I ran into even stranger problems when there was a .frm file present for
the notes database files, though that file won't normally exist unless the notes have been loaded as a database. The .Search method does work
though, so the below shows how to essentially get data from all transcript notes into an ADO.NET DataTable:
C#
sw.Notes.Search("Dep Exists", "Dep");
int noteCount = sw.Notes.Count;
string noteReport = noteCount + " transcript notes: \r\n";
if (noteCount > 0)
{
DataTable noteTable = new DataTable("Notes");
noteTable.Columns.Add("Id", typeof(int));
noteTable.Columns.Add("Deposition", typeof(string));
noteTable.Columns.Add("Author", typeof(string));
noteTable.Columns.Add("Text", typeof(string));
sw.Notes.MoveFirst();
for (int i = 0; i < noteCount; i++)
{
noteTable.Rows.Add(i + 1, sw.Notes.Dep, sw.Notes.Author, sw.Notes.Text);
sw.Notes.MoveNext();
}
}