Friday, August 19, 2016

Comparing Nullable Integer to Integer.

I only recently found out that you can create nullable integers. In other words, the value of your integer variable can be Nothing.
Dim nullableInteger as Integer? = Nothing
This causes problems when attempting to compare a nullable integer to a regular integer. How do you compare an integer to Nothing?
Does 0 = Nothing or 0 <> Nothing?
Is 1 > Nothing or 1 < Nothing or 1 = Nothing?
In my case I was taking a nullable integer in an Entity Framework Model and converting it to an integer in the ViewModel. I converted a Nothing value in the Model to a 0 in the ViewModel. But later when I made changes in the ViewModel I wanted to compare the value in the ViewModel and see if it had changed compared to the original Model value.  This was causing me problems.
Dim int As Integer = 0
Dim nullableInt As Integer? = Nothing
Dim Result as Boolean = (integer <> nullableInt)
This throws a System.InvalidOperationException("Nullable object must have a value")
I then tried casting the nullable integer to integer.  http://stackoverflow.com/a/2228484.  Supposedly this would convert a null value to 0.
Dim int As Integer = 0 
Dim nullableInt As Integer? = Nothing 
Dim Result as Boolean = (integer <> CType(nullableInt, Integer))
I ended up with the same error.

Ultimately I ended up finding two different solutions.
Dim int As Integer = 0 
Dim nullableInt As Integer? = Nothing 
Dim Result as Boolean = (integer <> If(nullableInt, 0))
http://stackoverflow.com/a/2228529
Dim int As Integer = 0 
Dim nullableInt As Integer? = Nothing 
Dim Result as Boolean = (integer <> nullableInt.GetValueOrDefault)
http://stackoverflow.com/a/10237279

Either one would allow you to specify the default value to use if the nullable value is null. GetValueOrDefault will take an optional parameter to specify the default value.   

Monday, April 20, 2015

Debugging errors that have already been caught in a Try Catch block.

I was having issues finding errors that were being caught in a Try Catch block and never handled.
Try
  <Code that throws an error>
Catch
End Try
With a large amount of errors being swallowed whole like this, I was having trouble determining where an issue may have developed in the code because of something I changed.  On the surface everything appeared to run fine since no errors bubbled to the surface. However, I wouldn't get the results I was expecting.  This often meant stepping through individual lines of code until I stumbled on the culprit. What I found is that you can force Visual Studio to break on thrown errors even if they are handled in a Try Catch block.

  • Either use "Ctrl-Alt-E" or on the Menu bar -> Debug -> Exceptions...
  • Check the "Thrown" box for the exceptions you want to break on



Friday, August 22, 2014

Line break in exchange appointments

I'm using the EWS (Exchange Web Service) Api with VB.Net to create appointments and I couldn't get it to accept the newline character.  Everything kept getting printed on one line and seemed to ignore my newline formatting.  vbNewLine didn't seem to work.  I also read something about having to put in extra spaces at the beginning or the end of the line, but that also didn't work.  I finally found a post which advised that appointments are stored in html format.  What finally worked was the html line break "<br />".

Thanks to Luke for the answer.

Wednesday, August 20, 2014

Registering a DLL file

The application I am working on uses Windows Image Acquisition 2.0 to access and control a scanner.  The problem was that after I installed and then uninstalled the program, I kept getting the error 'WIA' is not declared. It may be inaccessible due to its protection level. That should have been easy enough to fix, just reference the Microsoft Windows Image Acquisition Library v2.0.  The problem was that it wasn't there.  (Or at least I couldn't see it.)  I finally figured out that Gary didn't have version 2.0 on his XP computer and had to get a copy and register it separately.  When the program was installed, it registered the wiaaut.dll file to the one Gary included in the program files instead of the system32 folder.  As soon as I uninstalled the program, there went my reference to "WIA".  To fix the problem, I had to re-register the copy that was still in the system32 folder.  After I rebuilt the program, we also had to re-register wiaaut.dll on all the computers the program was installed on.



Here is how to do it.
  1. From the start bar, type cmd in the search field (don't hit enter)
  2. Right click cmd.exe and run as administrator (goes directly to system32 folder)
  3. At the prompt type: regsvr32 wiaaut.dll (hit enter)
To unregister the same dll
  1. Pull up the same cmd prompt
  2. At the prompt type: regsvr32 /u wiaaut.dll

Tuesday, August 12, 2014

Using VB.Net to check a checkbox on a pdf

It took me a little while to figure out how to check and uncheck a checkbox on a pdf form using VB.Net. The value of the checkbox has to be set to either "0" for unchecked or "1" for checked.  Here is the code I used to access the form and get to the checkbox.

' Reference to Acrobat application

Dim gApp As Acrobat.CAcroApp

'IAC objects
Dim gPdDoc As Acrobat.CAcroPDDoc

Dim formApp As AFORMAUTLib.AFormApp
Dim acroForm As AFORMAUTLib.Fields = Nothing
Dim field As AFORMAUTLib.Field

'Initialize Acrobat by creating App object
gApp = CreateObject("AcroExch.App")

' Initialize the PDF object
gPdDoc = CreateObject("AcroExch.PDDoc")

' Open an example PDF file in acrobat
If gPdDoc.Open("C:\example.pdf") Then 
   
   ' I'm still not sure what all of this does
   s = gPdDoc.GetFileName
   gPdDoc.OpenAVDoc(s)

   formApp = CreateObject("AFormAut.App")
  
   ' Get a reference to the fields from the form 
   acroForm = formApp.Fields

   ' Get a reference to the particular checkbox field 
   ' This uses the data structure of the form to find the form, 
   ' then page, then fieldname
   field = acroForm.Item("form1[0].#subform[0].Checkbox3[0]")
   
   ' Set the checkmark to "on"
   field.Value = "1"

   ' Set the checkmark to "off"
   field.Value = "0"
 
Else
   MsgBox("Failed to open")
End If

Monday, August 11, 2014

Dynamic pdf causing issues - unable to access form fields

I just figured out an issue that I don't think Gary ever got to the bottom of.  It all came down to the fact that not all pdf forms are created equal, and some of the forms we were using were getting saved in a different format that wasn't working with our code.  It would appear that pdf's can come in about 4 different formats.

From the adobe blog:

Flat PDF – A PDF with no XFA stream and no non-signature elements. Basically there are no fields in the document. It is important to note that a “Flat” PDF may still have some layers, such as the comment layer. In this case the flatness refers to the lack of data fields. 
Static PDF – A PDF which contains an XFA stream and the form layout does not change. Static forms may be interactive (a user can still fill in fields). If a dynamic XDP is rendered with LiveCycle Forms with the Render At Client option set to “No” then the resulting PDF is no longer dynamic – it is now static and behaves like any other static PDF.
Dynamic PDF – Dynamic PDFs allow the layout of the form to be altered either through user interaction or through script. An example is a form that adds subforms based on a user input. If a static XDP is rendered with LiveCycle Forms with the Render At Client option set to “Yes” then the resulting PDF is no longer static – it is now dynamic and behaves like any other dynamic PDF. 
Acroform – A non-XFA based PDF form, usually created directly in Adobe Acrobat (as opposed to using LiveCycle Designer).
When I tried running the following code
formApp = CreateObject("AFormAut.App")
acroForm = formApp.Fields
If the form was saved in Adobe LiveCycle as Static, acroForm would contain all of the fields from the form, however if it was saved as dynamic, no error was thrown, but acroForm would not contain any fields.  Both static and dynamic forms use XFA streams (Adobe's flavor of xml) to render the pages, but the underlying structure and the way the form is displayed can be dramatically changed in a dynamic form.  It would appear that my code was unable to access the fields, because the structure of the fields on a dynamic form can change after it is rendered.  A field that was on page 1 to start with could end up on page 10 after the client using the form made some selections that altered the form or even problematically before the form was first rendered.  

To fix my issue, I just went into Adobe Lifecycle and used the save as function to save the dynamic forms as static forms.

Thanks to the following links that helped me figure this issue out.

Tuesday, August 5, 2014

Installing a Service

I learned how to install a service yesterday from the command line.
  1. Pull up a command window
    • Start bar, type cmd and click cmd.exe.
  2. Change directory to the correct Microsoft.net framework: For me the directory was at:
    • cd C:\Windows\Microsoft.NET\Framework\v4.0.30319
  3. Execute installutil
    • C:\Windows\Microsoft.NET\Framework\v4.0.30319>installutil C:\(location of the service)\Myservice\Bin\Myservice.exe
  4. Start the service
    • Open the Window Services list
      1. Open a run box.
      2. Type services.msc and press return.
    • Right Click the service and select Start.


When making changes to the Service, make sure to uninstall the service before re-installing it.
  1. Stop the service
    • Open the Window Services list
      1. Open a run box. 
      2. Type services.msc and press return.
    • Right Click the service and select Stop.
  2. Close the Window Services list
  3. Pull up a command window
    • Start bar, type cmd and click cmd.exe.
  4. Change directory to the correct Microsoft.net framework: For me the directory was at:
    • cd C:\Windows\Microsoft.NET\Framework\v4.0.30319
  5. Execute installutil with /U Parameter
    • C:\Windows\Microsoft.NET\Framework\v4.0.30319>installutil /U C:\(location of the service)\Myservice\Bin\Myservice.exe

Thanks to Jayesh Jain for the great article on Creating a Windows Service in VB.NET