CSV Creation from two tables with URL for user to click on
One thing that will help is to replace the ArrayList with a List(Of String).  This will eliminate all the calls to ToString every time you want to get the value of an item in the list.  Also you can build the output string as you add the items, rather than iterating over it again.

Dim arrNames As New List(Of String)
With arrNames
    .Add("UPRN")
    str.Append("=" &amp; Chr(34) &amp; "UPRN" &amp; Chr(34) &amp; ",")
    .Add("BuildingNo")
    str.Append("=" &amp; Chr(34) &amp; "BuildingNo" &amp; Chr(34) &amp; ",")
    .Add("Street")
    str.Append("=" &amp; Chr(34) &amp; "Street" &amp; Chr(34) &amp; ",")
    .Add("Postcode")
    str.Append("=" &amp; Chr(34) &amp; "Postcode" &amp; Chr(34) &amp; ",")
    .Add("ItemRef")
    str.Append("=" &amp; Chr(34) &amp; "ItemRef" &amp; Chr(34) &amp; ",")
    .Add("SurveyDate")
    str.Append("=" &amp; Chr(34) &amp; "SurveyDate" &amp; Chr(34) &amp; ",")
    .Add("OverallRiskCategory")
    str.Append("=" &amp; Chr(34) &amp; "OverallRiskCategory" &amp; Chr(34) &amp; ",")
    .Add("SurveyorsComments")
    str.Append("=" &amp; Chr(34) &amp; "SurveyorsComments" &amp; Chr(34) &amp; ",")
End With


Also in this line:

str.Append("=" &amp; Chr(34) &amp; Trim(Replace(If(TryCast(datarow(arrNames(i).ToString).ToString, String), ""), vbTab, " ") &amp; Chr(34) &amp; ","))


The TryCast is redundant since calling the ToString method will always return some sort of a string.