Excel VBA: Macro to only export non blank cells - excel

Good day everyone,
I have this macro, which exports all cells with formulas, BUT with blank outputs.
I only want the cells displaying as non blank to export. Any ideas?
Sub Export_A()
Dim sPath As String
Dim SFile As String
Dim nLog As Integer
sPath = "C:\AAAWork\"
SFile = sPath & ActiveSheet.Range("P9") & ".txt"
nfile = FreeFile
Open SFile For Output As #nfile
For i = 1 To ActiveSheet.UsedRange.Rows.Count
Set ThisCell = ActiveSheet.Range("A" & i)
If ThisCell.Text <> "" Then
' sInDate = ThisCell.Text
'sOutDate = Format(ThisCell.Value, "mm/yyyy")
sOutDate = Format(ThisCell.Value, "yyyy-mm")
'stemp = """" & sOutDate & """" this gives the date the " in the
beginning and end
stemp = "" & sOutDate & ""
For j = 1 To 10
If j = 1 Or j = 2 Or j = 9 Then
stemp = stemp & ";" & ThisCell.Offset(0, j)
Else
'stemp = stemp & "," & """" & ThisCell.Offset(0, j) & """" This
gives every value a " beginning and end
stemp = stemp & ";" & ThisCell.Offset(0, j)
End If
Next
End If
Print #nfile, stemp
Next
Close #nfile
MsgBox ("Completed a file called " & SFile & " has been generated")
End Sub
This is an interesting way of exporting to CSV, but it was inherited and does everything else very well.

Try placing the Write line at the end of the For loop
Sub Export_A()
Dim sPath As String
Dim SFile As String
Dim nLog As Integer
sPath = "C:\AAAWork\"
SFile = sPath & ActiveSheet.Range("P9") & ".txt"
nfile = FreeFile
Open SFile For Output As #nfile
For i = 1 To ActiveSheet.UsedRange.Rows.Count
Set ThisCell = ActiveSheet.Range("A" & i)
If ThisCell.Text <> "" Then
' sInDate = ThisCell.Text
'sOutDate = Format(ThisCell.Value, "mm/yyyy")
sOutDate = Format(ThisCell.Value, "yyyy-mm")
'stemp = """" & sOutDate & """" this gives the date the " in the beginning and end
stemp = "" & sOutDate & ""
For j = 1 To 10
stemp = stemp & ";" & ThisCell.Offset(0, j)
Next
Print #nfile, stemp
End If
Next
Close #nfile
MsgBox ("Completed a file called " & SFile & " has been generated")
End Sub

first you don't need this if statement as the output is the same if it's true or false
If j = 1 Or j = 2 Or j = 9 Then
stemp = stemp & ";" & ThisCell.Offset(0, j)
Else
'stemp = stemp & "," & """" & ThisCell.Offset(0, j) & """" This gives every value a " beginning and end
stemp = stemp & ";" & ThisCell.Offset(0, j)
End If
If the blanks are in the following columns you could change to code to:
If ThisCell.Offset(0, j) <> "" Then
stemp = stemp & ";" & ThisCell.Offset(0, j)
End If
Which will skip blank columns

Related

Getting Record Tags from Excel to an XML file using Visual Basic Application script

I'm brand new to VBA and I have got a script that turns an Excel into a XML file.
What I need is to change it so that rather using a predefined Record Tag name, it uses data given in the Excel data table.
If we take this Excel table as an example, the XML file would end up being:
DeclarationFile>
<ID>
<k2>5555.555</k2>
<k7>2222.222</k7>
<k15>33.333</k15>
</ID>
<ID>
<k2>4444.444</k2>
<k7>1111.111</k7>
<k15>66.666</k15>
</ID>
<ID>
<k2>333.33</k2>
<k7>5.55</k7>
<k15>7.77</k15>
</ID>
</DeclarationFile>
But I need to change the code so that it uses the R14, R17 etc instead of ID
The whole code:
Sub CreateXMLFile()
Dim MN_Row As Integer, MN_Column As Integer, MN_TEMP As String, mn_YesOrNo As Variant, mndefine_folder As String
Dim mn_XML_FileName As String, mn_XML_Record_Name As String, mn_LF As String, mn_rtc1 As Integer
Dim mn_first_range As String, mn_second_range As String, mn_tt As String, mn_FieldName(99) As String
mn_LF = Chr(10) & Chr(13)
mndefine_folder = "C:\"
mn_YesOrNo = MsgBox("Vajadzigs:" & mn_LF _
& "1. XML File Name" & mn_LF _
& "2. Record Tag Name" & mn_LF _
& "3. A Range of Cells Containing Column Headers" & mn_LF _
& "4. A Range of Cells Containing the Data Table." & mn_LF _
& "If You Are Ready To Proceed, Click 'Yes'.", vbQuestion + vbYesNo, "CreateXMLFile")
If mn_YesOrNo = vbNo Then
Debug.Print "User Canceled With 'No'"
Exit Sub
End If
mn_XML_FileName = GapFiller(InputBox("1. Enter the XML File Name:", "CreateXMLFile", "xml_file"))
If Right(mn_XML_FileName, 4) <> ".xml" Then
mn_XML_FileName = mn_XML_FileName & ".xml"
End If
mn_XML_Record_Name = GapFiller(InputBox("2. Enter The Record Tag Name:", "CreateXMLFile", "ID"))
mn_first_range = InputBox("3. Enter The Range of Cells Containing Column Headers:", "CreateXMLFile", "A1:B1")
If MN_DataRange(mn_first_range, 1) <> MN_DataRange(mn_first_range, 2) Then
MsgBox "Error: Headers Must Be In The Same Row" & mn_LF & "Atcelts", vbOKOnly + vbCritical, "CreateXMLFile"
Exit Sub
End If
MN_Row = MN_DataRange(mn_first_range, 1)
For MN_Column = MN_DataRange(mn_first_range, 3) To MN_DataRange(mn_first_range, 4)
If Len(Cells(MN_Row, MN_Column).Value) = 0 Then
MsgBox "Error: Header Contains Empty Cell" & mn_LF & "Canceled", vbOKOnly + vbCritical, "CreateXMLFile"
Exit Sub
End If
mn_FieldName(MN_Column - MN_DataRange(mn_first_range, 3)) = GapFiller(Cells(MN_Row, MN_Column).Value)
Next MN_Column
mn_second_range = InputBox("4. Enter The Range of Cells Containing the Data Table:", "CreateXMLFile", "A2:B2")
If MN_DataRange(mn_first_range, 4) - MN_DataRange(mn_first_range, 3) <> MN_DataRange(mn_second_range, 4) - MN_DataRange(mn_second_range, 3) Then
MsgBox "Error: There Are More Or Less Headers Than Columns of Data" & mn_LF & "Canceled", vbOKOnly + vbCritical, "CreateXMLFile"
Exit Sub
End If
mn_rtc1 = MN_DataRange(mn_second_range, 3)
If InStr(1, mn_XML_FileName, ":\") = 0 Then
mn_XML_FileName = mndefine_folder & mn_XML_FileName
End If
Open mn_XML_FileName For Output As #1
Print #1, "<?xml version=" & Chr(34) & "1.0" & Chr(34) & " encoding=" & Chr(34) & "ISO-8859-1" & Chr(34) & "?>"
Print #1, "<DeclarationFile>"
For MN_Row = MN_DataRange(mn_second_range, 1) To MN_DataRange(mn_second_range, 2)
Print #1, "<" & mn_XML_Record_Name & ">"
For MN_Column = mn_rtc1 To MN_DataRange(mn_second_range, 4)
Print #1, "<" & mn_FieldName(MN_Column - mn_rtc1) & ">" & AmpersandEliminate(CheckForm(MN_Row, MN_Column)) & "</" & mn_FieldName(MN_Column - mn_rtc1) & ">"
Next MN_Column
Print #1, "</" & mn_XML_Record_Name & ">"
Next MN_Row
Print #1, "</DeclarationFile>"
Close #1
MsgBox mn_XML_FileName & " izveidots." & mn_LF & "Completed", vbOKOnly + vbInformation, "CreateXMLFile"
Debug.Print mn_XML_FileName & " saved"
End Sub
Function MN_DataRange(Rng_As_Text As String, MN_Item As Integer) As Integer
Dim MN_user_range As Range
Set MN_user_range = Range(Rng_As_Text)
Select Case MN_Item
Case 1
MN_DataRange = MN_user_range.Row
Case 2
MN_DataRange = MN_user_range.Row + MN_user_range.Rows.Count - 1
Case 3
MN_DataRange = MN_user_range.Column
Case 4
MN_DataRange = MN_user_range.Columns(MN_user_range.Columns.Count).Column
End Select
Exit Function
End Function
Function GapFiller(mn_my_Str As String) As String
Dim mn_Position As Integer
mn_Position = InStr(1, mn_my_Str, " ")
Do While mn_Position > 0
Mid(mn_my_Str, mn_Position, 1) = "_"
mn_Position = InStr(1, mn_my_Str, " ")
Loop
GapFiller = LCase(mn_my_Str)
End Function
Function CheckForm(mn_Row_Number As Integer, mn_Column_Number As Integer) As String
CheckForm = Cells(mn_Row_Number, mn_Column_Number).Value
If IsNumeric(Cells(mn_Row_Number, mn_Column_Number).Value) Then
CheckForm = Format(Cells(mn_Row_Number, mn_Column_Number).Value, "#,##0 ;(#,##0)")
End If
If IsDate(Cells(mn_Row_Number, mn_Column_Number).Value) Then
CheckForm = Format(Cells(mn_Row_Number, mn_Column_Number).Value, "dd mmm yy")
End If
End Function
Function AmpersandEliminate(mn_my_Str As String) As String
Dim mn_Position As Integer
mn_Position = InStr(1, mn_my_Str, "&")
Do While mn_Position > 0
Mid(mn_my_Str, mn_Position, 1) = "+"
mn_Position = InStr(1, mn_my_Str, "&")
Loop
AmpersandEliminate = mn_my_Str
End Function
Since I am completely clueless with VBA, I was getting array errors and "argument not optional"
Any tips on where to start are appreciated!
Try this:
Sub CreateXMLFile()
Const THE_FOLDER As String = "C:\"
Dim ws As Worksheet, rngData As Range, fName As String, rw As Long, col As Long
Dim xml As String, tagId As String, tagVal As String, v
If MsgBox("Vajadzigs:" & vbLf & "1. XML File Name" & vbLf & _
"2. A Range of Cells Containing the Data Table (with headers)." & vbLf & _
"If You Are Ready To Proceed, Click 'Yes'.", vbQuestion + vbYesNo, "CreateXMLFile") <> vbYes Then
Debug.Print "User Canceled With 'No'"
Exit Sub
End If
'would be better to use `Application.GetSaveAsFileName` here...
fName = Application.GetSaveAsFilename(filefilter:="XML (*.xml),*.xml", _
Title:="1. Select SaveAs name for XML file")
On Error Resume Next 'ignore error if not range selected
Set rngData = Application.InputBox("2. Select the range with data (include headers):", _
"CreateXMLFile", Type:=8)
On Error Resume Next 'stop ignoring error
If rngData Is Nothing Then
Debug.Print "User did not select a range"
Exit Sub
End If
Open fName For Output As #1
Print #1, "<?xml version=""1.0"" encoding=""ISO-8859-1""?>"
Print #1, "<DeclarationFile>"
For rw = 2 To rngData.Rows.Count
tagId = rngData.Cells(rw, 1).Value
Print #1, "<" & tagId & ">"
For col = 2 To rngData.Columns.Count
tagVal = rngData.Cells(1, col).Value
v = rngData.Cells(rw, col).Value
Print #1, "<" & tagVal & ">" & Replace(CheckForm(v), "&", "+") & "</" & tagVal & ">"
Next col
Print #1, "</" & tagId & ">"
Next rw
Print #1, "</DeclarationFile>"
Open fName For Output As #1
Close #1
MsgBox fName & " izveidots." & vbLf & "Completed", vbOKOnly + vbInformation, "CreateXMLFile"
Debug.Print fName & " saved"
End Sub
Function CheckForm(v) As String
If IsNumeric(v) Then v = Format(v, "#,##0 ;(#,##0)")
If IsDate(v) Then v = Format(v, "dd mmm yy")
CheckForm = CStr(v)
End Function

Export a range to new csv file, but the first row should be clear

This code exports a range of values that I want to a new csv file, but it should start at row 2, so I can fill the first row with a headline (another range value).
Sub TestRange()
Dim ws As Worksheet, fd As FileDialog, rngTest As Range, rngExport As Range, fltr As FileDialogFilter
Dim start As Long
start = 2
' Dim jahr As Integer
' jahr = Date
'Nach jeweiliger Zeit wird Datenreihe (start ab) ausgewählt
If Time < TimeValue("11:15") Then
Do Until Daten.Range("ov" & start) = Date + 1
start = start + 1
Loop
Else
Do Until Daten.Range("ov" & start) = Date + 2
start = start + 1
Loop
End If
'Worksheet auf dem die Daten stehen
Set ws = Worksheets("Daten")
'Zelle die auf Inhalt überprüft werden soll
Set rngTest = ws.Range("ov2")
'Bereich der exportiert wird
Set rngExport = ws.Range("ov" & start & ":ow5000")
If rngTest.Text <> "" Then
Set fd = Application.FileDialog(msoFileDialogSaveAs)
'Filename
fd.InitialFileName = "LG" & " " & Diagramm.Range("a5").Value & " " & "RZ" & " " & Format(Date, "mmmm") & " " & Format(Date, "yyyy") & "_" & "MW" & "_" & "ab" & " " & Daten.Range("ov" & start).Value
' Application.Dialogs(xlDialogSaveAs).Show filenameComplete
With fd
.Title = ""
'Filterindex für CSV-Dateien ermitteln
For i = 1 To .Filters.count
If .Filters(i).Extensions = "*.csv" Then
.FilterIndex = i
Exit For
End If
Next
'Wenn OK geklickt wurde starte Export
If .Show = True Then
ExportRangeAsCSV rngExport, ";", .SelectedItems(1)
End If
End With
End If
End Sub
'Prozedur für den Export eines Ranges in eine CSV-Datei
Sub ExportRangeAsCSV(ByVal rng As Range, delim As String, filepath As String)
Dim arr As Variant, line As String, csvContent As String, fso As Object, csvFile As Object
Set fso = CreateObject("Scripting.FileSystemObject")
Set csvFile = fso.OpenTextFile(filepath, 2, True)
arr = rng.Value 'Filter
If IsArray(arr) Then
For r = 1 To UBound(arr, 1)
line = ""
For c = 1 To UBound(arr, 2)
If c < UBound(arr, 2) Then
line = line & """" & arr(r, c) & """" & delim
Else
line = line & """" & arr(r, c) & """"
End If
Next
csvContent = csvContent & line & vbNewLine
Next
csvFile.Write (csvContent)
csvFile.Close
Else
MsgBox "Bereich besteht nur aus einer Zelle!", vbExclamation
End If
Set fso = Nothing
Set csvFile = Nothing
End Sub
I copied this code from the internet and it works, but I couldn't find a solution.
How can I change the code so my csv file has the first row clear, so that i can write the headlines of the two columns in the first row?
If IsArray(arr) Then
' new code
Dim col as range
For Each col In rng.Columns
If Len(line) > 0 Then line = line & delim
line = line & """" & rng.Parent.Cells(1, col.Column) & """"
Next
csvContent = line & vbNewLine
' existing code
For r = 1 To UBound(arr, 1)

Generate XML File with VBA

I'm trying to generate an XML file with VBA code.
My goal is to alter Excel data, and then to export this data into a valid XML file. There's only one row of data and one row for the name of the tags which I want to have the data inside.
How can I run through all the data and generate an XML file?
Some sample data (My original file has more columns and data).
(The yellow data is my first block in XML and the green data my second block.)
Here's how the XML File should look:
<?xml version="1.0" encoding="UTF-8"?>
<NmLoader>
<csvBeginTypeDefView handler ="TypeDefinition">
<csvattTemplate>LW</csvattTemplate>
<csvnameSpace>default</csvnameSpace>
<csvname>Tires</csvname>
<csvcontainerDomain/>
<csvtypeParent>Wheels</csvtypeParent>
</csvBeginTypeDefView>
<csvBeginAttributeDefView handler = "AttributeDefinition">
<csvname>TiresAT</csvname>
<csvattDefClass>Definition</csvattDefClass>
<csvdatatype>String</csvdatatype>
<csvIBA>TiresAT</csvIBA>
<csvQoM/>
</csvBeginAttributeDefView>
</NmLoader>
My Code:
Public Sub GenerateXML()
Dim sht As Worksheet
Dim loLetzteZ As Long, loLetzteS As Long, i As Long
Dim rBereich As Range, rng As Range
Dim sTagO As String, sTagC As String, sTagOEnd As String, sTagCStart As String
Dim sZeile As String
Dim strPfad As String
Dim strText As String
sTagO = "<"
sTagOEnd = "/>"
sTagC = ">"
sTagCStart = "</"
Set sht = Worksheets("Data")
'determine the last possible row
loLetzteZ = sht.Cells(Rows.Count, 1).End(xlUp).Row
'determine the last possible column
loLetzteS = sht.Cells(1, Columns.Count).End(xlToLeft).Column
'set me the area for the complete worksheet
Set rBereich = sht.Range("A2:" & Cells(loLetzteZ, loLetzteS).Address)
Application.ScreenUpdating = False
strPfad = ActiveWorkbook.Path & "\Data" & ".xml"
'row for row
For Each rng In rBereich.Rows
With rng
'column for column
For i = 1 To .Columns.Count
'If the tag is empty, then close this
If IsEmpty(.Cells(1, i)) Then
sZeile = sZeile & sTagO & Cells(1, i) & sTagOEnd
Else
'Opening Tag
sZeile = sZeile & sTagO & Cells(1, i) & sTagC
'Data for the tags
sZeile = sZeile & .Cells(1, i)
'End of Tags
sZeile = sZeile & sTagCStart & Cells(1, i) & sTagC
End If
'Write line with distance
sZeile = sZeile & vbCrLf
Next
'Write line with distance
sZeile = sZeile & vbCrLf & vbCrLf
'Open file and write the text
Call InDateiSchreiben(strPfad, sZeile, True)
End With
Next
Application.ScreenUpdating = True
End Sub
Other Solutions I tried:
I've already mapped the XML with Excel, but Excel is not able to export such an XML Schema.
I wrote code in VBA (I'm a beginner) by looking through posts regarding an XML Export.
Try this
Function GetXmlElement(sTagName As String, _
sValue As String, _
Optional bUseEmptyTags As Boolean = False, _
Optional bMultiline As Boolean = False) As String
Dim sStartOpen As String: sStartOpen = "<"
Dim sClose As String: sClose = ">"
Dim sEndOpen As String: sEndOpen = "</"
Dim sEmptyClose As String: sEmptyClose = " />"
Dim sTab As String: sTab = " "
Dim sTagValSeparator As String
Dim sValTagSeparator As String
If bMultiline Then
sTagValSeparator = Chr(10) & sTab
sValTagSeparator = Chr(10)
End If
If Len(sValue) = 0 And bUseEmptyTags Then
GetXmlElement = sStartOpen & sTagName & sEmptyClose
Else
GetXmlElement = sStartOpen & sTagName & sClose & sTagValSeparator & _
Replace(sValue, Chr(10), Chr(10) & sTab) & _
sValTagSeparator
If InStr(1, sTagName, " ") > 0 Then
'tag has attributes'
sTagName = Left(sTagName, InStr(1, sTagName, " ") - 1)
End If
GetXmlElement = GetXmlElement & sEndOpen & sTagName & sClose
End If
End Function
Function GetXMLOutput() As String
Dim lLastCol As Long
Dim i As Long
Dim lCsvBeginCol As Long
Dim sTagName As String
Dim sInnerElements As String
Dim sOutput As String
With ThisWorkbook.Sheets("Data")
lLastCol = .Cells(1, Columns.Count).End(xlToLeft).Column
lCsvBeginCol = 1
For i = 1 To lLastCol
sTagName = .Cells(1, i)
If Left(sTagName, 8) = "csvBegin" And i > lCsvBeginCol Or i = lLastCol Then
' build the outer element
sTagName = .Cells(1, lCsvBeginCol) & "=""" & .Cells(2, lCsvBeginCol) & """"
If Len(sOutput) > 0 Then
sOutput = sOutput & Chr(10) & Chr(10)
End If
sOutput = sOutput & GetXmlElement(sTagName, sInnerElements, True, True)
lCsvBeginCol = i
sInnerElements = ""
ElseIf i <> lCsvBeginCol Then
' build the inner elements
If Len(sInnerElements) > 0 Then sInnerElements = sInnerElements & Chr(10)
sInnerElements = sInnerElements & GetXmlElement(sTagName, .Cells(2, i), True)
End If
Next i
sOutput = GetXmlElement("NmLoader", sOutput, True, True)
sOutput = "<?xml version=""1.0"" encoding=""UTF-8""?>" & Chr(10) & Chr(10) & sOutput
GetXMLOutput = sOutput
Debug.Print sOutput
End With
End Function
Sub GenerateXML()
Dim sFilename As String
sFilename = ThisWorkbook.Path & "\Data.xml"
Open sFilename For Output As #1
Print #1, GetXMLOutput
Close #1
End Sub
Try
Option Explicit
Public Sub GenerateXML()
Dim sht As Worksheet
Set sht = Worksheets("Data")
Dim loLetzteZ As Long, loLetzteS As Long, i As Long
Dim rBereich As Range, rng As Range
Dim sZeile As String
Dim strPfad As String
Dim sTag As String, sTag1 As String, sData As String
'determine the last possible row
loLetzteZ = sht.Cells(Rows.Count, 1).End(xlUp).Row
'determine the last possible column
loLetzteS = sht.Cells(1, Columns.Count).End(xlToLeft).Column
'set me the area for the complete worksheet
Set rBereich = sht.Range("A2:" & Cells(loLetzteZ, loLetzteS).Address)
' output
strPfad = ActiveWorkbook.Path & "\Data" & ".xml"
sTag1 = ""
sZeile = "<?xml version=""1.0"" encoding=""UTF-8""?>" & vbCrLf _
& "<NmLoader>" & vbCrLf
'row for row
For Each rng In rBereich.Rows
With rng
'column for column
For i = 1 To .Columns.Count
sTag = Trim(sht.Cells(1, i))
sData = Trim(.Cells(1, i))
'If the tag is handler
If LCase(Right(sTag, 7)) = "handler" Then
sTag1 = Split(sTag, " ")(0) ' remove handler
sZeile = sZeile & "<" & sTag1 & " handler=""" & sData & """>"
' is it a closing tag
ElseIf sTag = sTag1 Then
sZeile = sZeile & "</" & sTag1 & ">" & vbCrLf
ElseIf Len(sData) > 0 Then
sZeile = sZeile & vbTab & "<" & sTag & ">" & sData & "</" & sTag & ">"
Else
sZeile = sZeile & vbTab & "<" & sTag & "/>"
End If
sZeile = sZeile & vbCrLf
Next
'Write line with distance
sZeile = sZeile & vbCrLf & "</NmLoader>" & vbCrLf
'Open file and write the text
Debug.Print sZeile
'Call InDateiSchreiben(strPfad, sZeile, True)
End With
Next
MsgBox strPfad & " created", vbInformation
End Sub

Solve runtime 91 error in Excel VBA textfile export

Very new to VBA and trying to create an automated textfile export.
Currently it works like a charm for row 1 and the textfile is created. But when adding data on row 2 as well I get:
Runtime error 91, Object variable or With block variable not set.
Any help would be much appreciated!
Sub Exportera()
Dim bKlar As Boolean
Dim bSkrivPSlut As Boolean
Dim bSkrivPStart As Boolean
Dim fsoExpFil As FileSystemObject
Dim fsoTextStream2 As TextStream
Dim sExportFile As String
Dim iSvar As Integer
Dim iSvar2 As Integer
Dim sSokvag As String
Dim sFilnamn As String
Dim sTemp As String
Dim sPFalt As String
Dim cVarde As Currency
Dim sDatum As String
'alright då skapar vi fil och skriver till den
Set fsoExpFil = New FileSystemObject
Range("K10").Select
sSokvag = Trim(ActiveCell.FormulaR1C1)
Range("K13").Select
sFilnamn = Trim(ActiveCell.FormulaR1C1)
If Not UCase(Right(sFilnamn, 4)) = ".TXT" Then
sFilnamn = sFilnamn & ".txt"
End If
sExportFile = sSokvag & "\" & sFilnamn
If sSokvag = "" Or sFilnamn = "" Then
MsgBox "Exporten avbryts då sökväg och filnamn saknas för exportfilen.", vbInformation, sAppName
Exit Sub
Else
If fsoExpFil.FileExists(sExportFile) = True Then
iSvar = MsgBox("Filen " & sFilnamn & " finns redan, skall den ersättas?", vbYesNo, sAppName)
If iSvar = vbNo Then
Exit Sub
End If
Else
iSvar = MsgBox("Är du säker att du vill exportera?", vbYesNo, "Exportera")
End If
End If
If iSvar = vbYes Then
Set fsoTextStream2 = fsoExpFil.OpenTextFile(sExportFile, ForWriting, True)
fsoTextStream2.WriteLine "Filhuvud"
fsoTextStream2.WriteLine vbTab & "Typ=" & """Anställda"""
sTemp = "SkapadAv=" & """"
sTemp = sTemp & "Importfil"
sTemp = sTemp & """"
fsoTextStream2.WriteLine vbTab & sTemp
fsoTextStream2.WriteLine vbTab & "DatumTid=" & "#" & Now & "#"
bKlar = False
i = 1
Sheets("Data").Select
While bKlar = False
i = i + 1
Range("A" & i).Select
If Trim(ActiveCell.FormulaR1C1) <> "" Then
If IsNumeric(ActiveCell.FormulaR1C1) Then
fsoTextStream2.WriteLine "PStart"
fsoTextStream2.WriteLine " Typ = ""Anställda"""
Range("A" & i).Select
If Trim(ActiveCell.FormulaR1C1) <> "" Then
fsoTextStream2.WriteLine " Anställningsnummer = " & ActiveCell.FormulaR1C1
End If
Range("B" & i).Select
If Trim(ActiveCell.Text) <> "" Then
fsoTextStream2.WriteLine " Namn=" & Trim(ActiveCell.FormulaR1C1)
End If
Range("D" & i).Select
If Trim(ActiveCell.Text) <> "" Then
fsoTextStream2.WriteLine " Utdelningsadress=" & ActiveCell.FormulaR1C1
End If
Range("E" & i).Select
If Trim(ActiveCell.Text) <> "" Then
fsoTextStream2.WriteLine " co_adress=" & ActiveCell.FormulaR1C1
End If
Range("G" & i).Select
If Trim(ActiveCell.Text) <> "" Then
fsoTextStream2.WriteLine " Postadress=" & ActiveCell.FormulaR1C1
End If
Range("F" & i).Select
If Trim(ActiveCell.Text) <> "" Then
fsoTextStream2.WriteLine " Postnummer=" & ActiveCell.FormulaR1C1
End If
Range("C" & i).Select
If Trim(ActiveCell.Text) <> "" Then
sTemp = ActiveCell.FormulaR1C1
sTemp = Mid(sTemp, 1, 6) & "-" & Mid(sTemp, 7)
fsoTextStream2.WriteLine " Personnummer=" & sTemp
End If
Range("H" & i).Select
If Trim(ActiveCell.Text) <> "" Then
fsoTextStream2.WriteLine " E_mail=" & ActiveCell.FormulaR1C1
End If
Range("I" & i).Select
If Trim(ActiveCell.Text) <> "" Then
sTemp = ActiveCell.FormulaR1C1
Range("AM" & i).Select
sTemp = sTemp & ActiveCell.FormulaR1C1
sTemp = Replace(sTemp, "-", "")
fsoTextStream2.WriteLine " Bankkontonummer=" & sTemp
End If
Range("J" & i).Select
If Trim(ActiveCell.Text) <> "" Then
sDatum = ActiveCell.Text
fsoTextStream2.WriteLine " Anställningsdatum=" & "#" & sDatum & "#"
End If
fsoTextStream2.WriteLine "PSlut"
fsoTextStream2.Close
MsgBox "Exporten är klar", vbInformation, sAppName
End If
Else
bKlar = True
End If
Wend
End If
End Sub
Your problem is not exactly what you'd be expecting.
Note that in your while loop, you close your filestream object at the end with fsoTextStream2.Close. What you'll be seeing is that it will successfully write the first line, but then close the file and then try to write to a file that is closed.
Simply moving this outside the loop (after wend) will fix your problem (Shown below).
fsoTextStream2.WriteLine "PSlut"
MsgBox "Exporten är klar", vbInformation, sAppName
End If
Else
bKlar = True
End If
Wend
fsoTextStream2.Close 'This line has been moved outside the loop
End If
End Sub
There's quite a few improvements for your code, if you alter it slightly to avoid .select calls. Also .value rather than .text might be useful if your cells have numeric input. Note that you can extract cell values without having them selected by using range("A" & i).value (or simply range("A" & i)) using worksheet("sheetname").range("A" & i) to access specific sheet cells. (cells(row, column) works just as well).

Hyperlinks.add changes hyperlink unwanted

I have used hyperlinks.add several times now and never had any problems with it.
Now I added a line of code: SourceBook.Sheets(ESN & "_SV" & SV).Hyperlinks.Add Anchor:=Range("A" & i), _
Address:=ToPath & NewName to my base code (which you can find under here). This should add a link to the newly created document.
The problem is that excel always says it cannot open the file. The link I enter via code is right, as I copied it with debug.print and it opened the file without a problem.
It came to my attention that the hyperlink I added was modified by excel when I hold my mouse over the hyperlink. I wonder how this is possible.
A second problem I encounterd is that when I enter the hyperlink manually and navigate manually to the file to make sure it takes the right file, excel still modifies my link and says "cannot open specified file".
Anyone an idea what might go wrong here? Thanks!
Code:
`Application.ScreenUpdating = False
Dim i, j, FSO As Object, SV, ESN, PartName, ToPath, FromPath, NewName, MsgBoxAnswer, TargetBook As Workbook, SourceBook As Workbook
Dim OS, PN, SN, ProjectNumber, Customer, StartDate, EndDate, LastRowCMM
ESN = ActiveWorkbook.ActiveSheet.Range("G2").Value
SV = ActiveWorkbook.ActiveSheet.Range("K2").Value
ProjectNumber = ActiveWorkbook.ActiveSheet.Range("A3").Value
Customer = ActiveWorkbook.ActiveSheet.Range("G3").Value
Set FSO = CreateObject("scripting.filesystemobject")
PGB.Min = 0
PGB.Value = 0
PGB.Max = 22
'Create main folder
If SV <> 1 Then
SV = "(SV " & SV & ")"
ToPath = "U:\tmo\vanmolle\fiches constat\Fiches constats #" & ESN & " " & SV
Else
ToPath = "U:\tmo\vanmolle\fiches constat\Fiches constats #" & ESN
End If
If FSO.folderexists(ToPath) = True Then
MsgBoxAnswer = MsgBox("Folder already created.", vbExclamation, "Folder exists.")
Exit Sub
End If
FSO.createfolder (ToPath)
'Create all Excel files & fill them in
For i = 6 To 27
FromPath = "U:\tmo\VANMOLLE\Fiches constat\Template fiches constat LEAP.xlsm"
If SV <> 1 Then
ToPath = "U:\tmo\vanmolle\fiches constat\Fiches constats #" & ESN & " " & SV & "\"
Else
ToPath = "U:\tmo\vanmolle\fiches constat\Fiches constats #" & ESN & "\"
End If
FSO.copyfile Source:=FromPath, Destination:=ToPath
NewName = "#" & ESN & "_" & ActiveWorkbook.ActiveSheet.Range("A" & i) & ".xlsm"
If SV <> 1 Then
FromPath = "U:\tmo\vanmolle\fiches constat\Fiches constats #" & ESN & " " & SV & "\Template fiches constat LEAP.xlsm"
Else
FromPath = "U:\tmo\vanmolle\fiches constat\Fiches constats #" & ESN & "\Template fiches constat LEAP.xlsm"
End If
Name FromPath As ToPath & NewName
Set SourceBook = ThisWorkbook
Set TargetBook = Workbooks.Open(ToPath & NewName)
TargetBook.Sheets("Sheet1").Activate
PartName = SourceBook.ActiveSheet.Range("A" & i).Value
OS = SourceBook.ActiveSheet.Range("D" & i).Value
PN = SourceBook.ActiveSheet.Range("B" & i).Value
SN = SourceBook.ActiveSheet.Range("C" & i).Value
If SN = "" Then SN = "N/A"
StartDate = SourceBook.ActiveSheet.Range("G" & i).Value
EndDate = SourceBook.ActiveSheet.Range("H" & i).Value
'check for right CMM
'LastRowCMM = TargetBook.Sheets("Révision CMM").Range("B6").End(xlDown).Row
'For j = 1 To LastRowCMM
'If PartName = TargetBook.Sheets("Révision CMM").Range("A" & j).Value Then ActiveWorkbook.ActiveSheet.Range("A23").Value = ActiveWorkbook.Sheets("Révision CMM").Range("B" & j).Value
'Next j
TargetBook.ActiveSheet.Range("B9").Value = PartName
TargetBook.ActiveSheet.Range("B10").Value = OS
TargetBook.ActiveSheet.Range("B11").Value = "# " & ESN
TargetBook.ActiveSheet.Range("B12").Value = PN
TargetBook.ActiveSheet.Range("B13").Value = SN
TargetBook.ActiveSheet.Range("E9").Value = StartDate
TargetBook.ActiveSheet.Range("E10").Value = EndDate
TargetBook.ActiveSheet.Range("B14").Value = ProjectNumber
TargetBook.ActiveSheet.Range("B15").Value = Customer
TargetBook.ActiveSheet.PageSetup.PrintArea = "$A$1:$E$39"
TargetBook.Close True
'Add hyperlink
SourceBook.Sheets(ESN & "_SV" & SV).Hyperlinks.Add Anchor:=Range("A" & i), _
Address:=ToPath & NewName
Application.Wait (Now + TimeValue("00:00:01"))
Progress.PGB.Value = i - 5
Progress.Lbl.Caption = "File " & i - 5 & " of 22 copied."
Next i
Application.ScreenUpdating = True`
First thing first - declare each variable explicitly. E.g.:
Dim i as Long, j as Long, FSO As Object, SV as String, ESN as String and etc.
The way in your code - Dim i, j, SV, ESN, PartName, ToPath they are declared as variant.
Second thing second - try something really very small to debug further. E.g. write this small piece:
Sub TestMe()
With Worksheets(1)
.Hyperlinks.Add anchor:=.Range("A1"), Address:="C:\Users\UserName\Desktop\test.docx"
End With
End Sub
and check whether it works. If it doesn't, debug further, check whether cells are locked or anything similar.

Resources