I am working on a project to read InfoPath XML files into a .NET form. I'm trying to get the .xsn version from the href in order to determine what version of the InfoPath form I should display. Since there is only 1 .xsn string in the XML File, I can use that, but I'm having trouble parsing out the file name.
http://servername/foldername/forms/fileNameV100.xsn
Here is an example of how you would parse the filename. You can use these techniques to parse out the version. Additional notes are in the comments of the code.
Private Function ParseXsnFileName(ByVal strTarget As String) As String
Dim strResult As String = String.Empty
'Get the location of where the .xsn extension starts.
Dim intExtensionLocation As Integer = strTarget.IndexOf(".xsn")
If intExtensionLocation >= 0 Then
'Now we will initiate a loop that iterates back character by character until we find
'the forward slash of the URL that preceedes the filename.
Dim bolStartFound As Boolean = False
Dim intCursor As Integer = intExtensionLocation
Do Until intCursor = 0 OrElse bolStartFound
If strTarget.Substring(intCursor, 1) = "/" Then
'Setting this to true exist the loop.
bolStartFound = True
End If
intCursor -= 1
Loop
If bolStartFound Then
'We found all of the pieces we need to parse out the filename.
'Add 2 because of the "intCursor -= 1" and because we don't want the / in the filename.
Dim intStartLocation As Integer = intCursor + 2
'Add 4 to StartLocation because we want the extension.
'Subtract intStartLocation from intExtensionLocation to get the length.
strResult = strTarget.Substring(intStartLocation, (intExtensionLocation - (intStartLocation + 4)))
End If
End If
Return strResult
End Function
Example Usage:
Dim strParseThis As String = "http://servername/foldername/forms/fileNameV100.xsn"
Dim strFileName As String = ParseXsnFileName(strParseThis)
Related
I am using the OpenXML library to auto generate Word files. I have a function that takes a group of files and merges them into one document. As I merge a new file into a document, I want each file to start on a new page. But, I don't want to have any blank pages. The code I have mostly works, but an issue comes up is if a file being merged in is a filled page, then a page break is still added, resulting in an empty page being added. I am not sure how to best deal with this, to prevent blank pages from being added. Here is my code:
Public Sub MergeFiles(ByVal filePaths As List(Of String), ByVal fileName As String)
Dim newFile As String = HttpRuntime.AppDomainAppPath & "PDF_Templates\TempFolder\catalog-" & Guid.NewGuid.ToString & ".docx"
File.Copy(fileName, newFile)
Dim counter As Integer = 0
For Each filePath As String In filePaths
Dim wordDoc As WordprocessingDocument = WordprocessingDocument.Open(newFile, True)
Using wordDoc
Dim mainPart As MainDocumentPart = wordDoc.MainDocumentPart
Dim altChunkId As String = "altChunkId" & counter
Dim chunk As AlternativeFormatImportPart = mainPart.AddAlternativeFormatImportPart(AlternativeFormatImportPartType.WordprocessingML, altChunkId)
Dim fileStream As FileStream = File.Open(filePath, FileMode.Open)
Using fileStream
chunk.FeedData(fileStream)
End Using
Dim AltChunk As AltChunk = New AltChunk()
AltChunk.Id = altChunkId
' Dont add a page break to the first page.
If counter > 0 Then
Dim last As OpenXmlElement = wordDoc.MainDocumentPart.Document.Body.Elements().LastOrDefault(Function(e) TypeOf e Is Paragraph OrElse TypeOf e Is AltChunk)
last.InsertAfterSelf(New Paragraph(New Run(New Break() With {
.Type = BreakValues.Page
})))
End If
mainPart.Document.Body.InsertAfter(Of AltChunk)(AltChunk, mainPart.Document.Body.Elements(Of Paragraph).Last())
mainPart.Document.Save()
wordDoc.Close()
End Using
counter = counter + 1
Next
End Sub
This topic is related to Loop through links and download PDF's
I am trying to convert my current VBA code into VBScript. I have already understood that I have to remove the variable types (As ... part of Dim statements) and use CreatObject to get those objects but otherwise everything should port as-is. DoEvents will also have to be replaced with something like Wscript.sleep.
I came up with some problems. Currently while running VBS file I am getting an error saying "Object required: 'MSHTML'". Pointing to line 65, where I have Set hDoc = MSHTML.HTMLDocument. I have tried to search on Google but got nothing helpful for this one.
How I should proceed with this one?
DownloadFiles("https://www.nordicwater.com/products/waste-water/")
Sub DownloadFiles(p_sURL)
Set xHttp = CreateObject("Microsoft.XMLHTTP")
Dim xHttp
Dim hDoc
Dim Anchors
Dim Anchor
Dim sPath
Dim wholeURL
Dim internet
Dim internetdata
Dim internetlink
Dim internetinnerlink
Dim arrLinks
Dim sLink
Dim iLinkCount
Dim iCounter
Dim sLinks
Set internet = CreateObject("InternetExplorer.Application")
internet.Visible = False
internet.navigate (p_sURL)
Do Until internet.ReadyState = 4
Wscript.Sleep 100
Loop
Set internetdata = internet.document
Set internetlink = internetdata.getElementsByTagName("a")
i = 1
For Each internetinnerlink In internetlink
If Left(internetinnerlink, 36) = "https://www.nordicwater.com/product/" Then
If sLinks <> "" Then sLinks = sLinks & vbCrLf
sLinks = sLinks & internetinnerlink.href
i = i + 1
Else
End If
Next
wholeURL = "https://www.nordicwater.com/"
sPath = "C:\temp\"
arrLinks = Split(sLinks, vbCrLf)
iLinkCount = UBound(arrLinks) + 1
For iCounter = 1 To iLinkCount
sLink = arrLinks(iCounter - 1)
'Get the directory listing
xHttp.Open "GET", sLink
xHttp.send
'Wait for the page to load
Do Until xHttp.ReadyState = 4
Wscript.Sleep 100
Loop
'Put the page in an HTML document
Set hDoc = MSHTML.HTMLDocument
hDoc.body.innerHTML = xHttp.responseText
'Loop through the hyperlinks on the directory listing
Set Anchors = hDoc.getElementsByTagName("a")
For Each Anchor In Anchors
'test the pathname to see if it matches your pattern
If Anchor.pathname Like "*.pdf" Then
xHttp.Open "GET", wholeURL & Anchor.pathname, False
xHttp.send
With CreateObject("Adodb.Stream")
.Type = 1
.Open
.write xHttp.responseBody
.SaveToFile sPath & getName(wholeURL & Anchor.pathname), 2 '//overwrite
End With
End If
Next
Next
End Sub
Function:
Function getName(pf)
getName = Split(pf, "/")(UBound(Split(pf, "/")))
End Function
Instead of Set hDoc = MSHTML.HTMLDocument, use:
Set hDoc = CreateObject("htmlfile")
In VBA/VB6 you can specify variable and object types but not with VBScript. You have to use CreateObject (or GetObject: GetObject function) to instantiate objects like MSHTML.HTMLDocument, Microsoft.XMLHTTP, InternetExplorer.Application, etc instead of declaring those using Dim objIE As InternetExplorer.Application for example.
Another change:
If Anchor.pathname Like "*.pdf" Then
can be written using StrComp function:
If StrComp(Right(Anchor.pathname, 4), ".pdf", vbTextCompare) = 0 Then
or using InStr function:
If InStr(Anchor.pathname, ".pdf") > 0 Then
Also, at the beginning of your sub, you do the following:
Set xHttp = CreateObject("Microsoft.XMLHTTP")
Dim xHttp
You should declare your variables before assigning them values or objects. In VBScript this is very relaxed, your code will work because VBScript will create undefined variables for you but it's good practice to Dim your variables before using them.
Except for Wscript.sleep commands, your VBScript code will work in VB6/VBA so you can debug your script in VB6 or VBA apps (like Excel).
Hi I am having some problems with saving img files using Visual Basic, the files are being named wrongly with the folder name being added to the start of the file name.
I parse a web address and then use the split address values to rename my files however the the path value seems to be added to the file as well.
The files in the photo should be named for example "DCAT040iMBE Test13.jpg"
but this file is being name "Test1DCAT040iMBE Test13.jpg"
Protected Sub GeneratedCode()
Dim path As String = "C:\Users\Grey\Documents\visual studio 2010\Projects\QRCodeGenerator\QRCodeGenerator\Output\"
LogoUpload.SaveAs(path + LogoUpload.FileName)
TextFile.SaveAs(path + TextFile.FileName)
Dim lines() As String = IO.File.ReadAllLines(path + TextFile.FileName)
For Each line As String In lines
Dim count As Integer
Dim encoder As New QRCodeEncoder()
encoder.QRCodeErrorCorrect = QRCodeEncoder.ERROR_CORRECTION.H
encoder.QRCodeScale = 10
Dim img As Bitmap = encoder.Encode(line)
Dim logo As System.Drawing.Image = System.Drawing.Image.FromFile(path + LogoUpload.FileName)
Dim left As Integer = (img.Width / 2) - (logo.Width / 2)
Dim top As Integer = (img.Height / 2) - (logo.Height / 2)
Dim g As Graphics = Graphics.FromImage(img)
Dim parseLine = line
Dim replaceDelimiter As String
If Not String.IsNullOrWhiteSpace(line) Then
replaceDelimiter = Replace(line, "&", "=")
End If
Dim fileNameSplit() As String = replaceDelimiter.Split("=")
Dim newFileName As String
Dim partTwo = fileNameSplit(1)
Dim partSix = fileNameSplit(5)
Dim objFSO
Dim newFolder As String
newFolder = "C:\Users\Grey\Documents\visual studio 2010\Projects\QRCodeGenerator\QRCodeGenerator\Output\" + partSix
objFSO = CreateObject("Scripting.FileSystemObject")
If (Not System.IO.Directory.Exists(newFolder)) Then
System.IO.Directory.CreateDirectory(newFolder)
End If
count += 1
g.DrawImage(logo, New Point(left, top))
newFileName = partTwo & " " & partSix & count & ".jpg"
img.Save(newFolder + newFileName, ImageFormat.Jpeg)
amountCreatedLbl.Text = count & " QRCodes Created"
logo.Dispose()
Next
End Sub
Could it be that I am generating my newFolder Values wrongly?
edited to add an example of data from the parsed txt file.
https://mywebsite.com/QRCode/default.aspx?materialcode=DTAT050&Logo=MyLogo&Companyloc=Test1
https://mywebsite.com/QRCode/default.aspx?materialcode=DCAT055iMB&Logo=MyLogo&Companyloc=Test1
https://mywebsite.com/QRCode/default.aspx?materialcode=DCAT040iMBE&Logo=MyLogo&Companyloc=Test1
https://mywebsite.com/QRCode/default.aspx?materialcode=DTAB060&Logo=MyLogo&Companyloc=Test1
https://mywebsite.com/QRCode/default.aspx?materialcode=DTAT050&Logo=MyLogo&Companyloc=Test2
https://mywebsite.com/QRCode/default.aspx?materialcode=DCAT055iMB&Logo=MyLogo&Companyloc=Test2
https://mywebsite.com/QRCode/default.aspx?materialcode=DCAT040iMBE&Logo=MyLogo&Companyloc=Test2
https://mywebsite.com/QRCode/default.aspx?materialcode=DTAB060&Logo=MyLogo&Companyloc=Test2
https://mywebsite.com/QRCode/default.aspx?materialcode=DTAT050&Logo=MyLogo&Companyloc=Test3
https://mywebsite.com/QRCode/default.aspx?materialcode=DCAT055iMB&Logo=MyLogo&Companyloc=Test3
https://mywebsite.com/QRCode/default.aspx?materialcode=DCAT040iMBE&Logo=MyLogo&Companyloc=Test3
https://mywebsite.com/QRCode/default.aspx?materialcode=DTAB060&Logo=MyLogo&Companyloc=Test
Looks like you are missing a slash on the line:
img.Save(newFolder + newFileName, ImageFormat.Jpeg)
It should be:
img.Save(newFolder + "\" + newFileName, ImageFormat.Jpeg)
The program doesn't realize that the newDirectory variable is supposed to be a directory, it's just being concatenated to the filename directly. A better option would be to use:
img.Save(System.IO.Path.Combine(newFolder, newFileName), ImageFormat.Jpeg)
The System.IO.Path.Combine() function automatically adds the missing slash between the directory and filename, as well as some additional checks to make sure the result is valid.
As a side note, I would also recommend using & instead of + when joining strings together. Hard to debug issues can come up when you do it that way. I would also recommend turning Option Strict On, you will see a couple of other warnings that come up with your code as is. But, to resolve your issue, the above will work.
I'm using Google's Finance Converter for converting currency, but I'm getting the error:
input string was not in a correct format
Here's my code:
Protected Sub btnGoogleApi_Click(sender As Object, e As EventArgs)
Dim amount As Decimal = 0
Dim fromCurrency As String
Dim toCurrency As String
amount = Decimal.Parse(txtAmount.Text.Trim(), System.Globalization.NumberStyles.Any, CultureInfo.InvariantCulture)
fromCurrency = ddlFrom.SelectedItem.Value
toCurrency = ddlTo.SelectedItem.Value
If amount <> 0 Then
Dim web As New WebClient()
Dim url As String = String.Format("http://www.google.com/finance/converter?a={0}&from={1}&to={2}", amount, fromCurrency.ToUpper(), toCurrency.ToUpper())
Dim response As String = web.DownloadString(url)
Dim regex As New Regex("rhs: \""(\d*.\d*)")
Dim rate As Decimal = System.Convert.ToDecimal(regex.Match(response).Groups(1).Value)
lblMessage.Text = ("Real-Time Rate: 1 " + ddlFrom.SelectedItem.Value & " = " & rate & " ") + ddlTo.SelectedItem.Value
End If
End Sub
You are getting that error on this line
Dim rate As Decimal = System.Convert.ToDecimal(regex.Match(response).Groups(1).Value)
because your regular expression does not match anything and you cannot convert an empty string to a decimal.
The Google Finance Converter you are using does not return the same response as the old iGoogle api. Instead it returns an HTML page string. I suggest you use another api that will be easier to read the output.
If not, just change you're regular expression to:
Dim regex As New Regex("<span class=bld>(\d*.\d*)")
The converted rate is in an HTML span tag with the class bld. My regular expression is not great but that should do.
If the output changes, you will need to adjust accordingly.
I do not have any experience with Unix coding besides navigating through directories and was wondering if someone could help me with writing a script to replicate what I am doing within .NET. I was told it would run faster since the .NET code is deployed remotely and sometimes using a mapped drive to access large amounts of folders runs slow. I basically am sorting files by moving files from selected folders to a group of folders based on the filename and sorting each based on the file date which is included in the filename.
Private Sub moveAllfiles(ByVal directoryStuff As String)
Dim templist As New ArrayList
Dim finalDestination As String = String.Empty
Dim pathName As String = String.Empty
Dim fileToDelete As String = String.Empty
Dim folderDate As String = String.Empty
Dim counter As Integer = 0
Dim folders = Directory.EnumerateDirectories(directoryStuff)
For Each item In folders
Dim files As String() = Directory.GetFiles(item)
//' if directory is empty delete folder
If Directory.GetFiles(item).Count = 0 Then
Directory.Delete(item)
Continue For
End If
For i As Integer = 0 To files.Count - 1
Try
counter += 1
Dim oInfo As New FileInfo(files(i))
// ' if file is empty or small delete it
If oInfo.Length <= 1 Then
File.Delete(files(i))
Continue For
End If
If Not files(i).EndsWith(".gz") Then
CompressFiles(files(i))
Continue For
End If
Dim objInfo As New FileInfo(files(i))
If Not objInfo.Name.Contains("Data_G_E") Then
If objInfo.Name.Contains("Data_G_P") Then
Dim pfiledate As String = objInfo.Name.Remove(20)
pfiledate = pfiledate.Remove(7, 5)
Dim ftempDirectory As String
= "M:\Archive\DataP\" + pfiledate & "\"
If Not Directory.Exists(ftempDirectory) Then
Directory.CreateDirectory(ftempDirectory)
Dim destdirectory As String = ftempDirectory
Dim ff As String = files(i)
fileToDelete = ff
File.Move(ff, destdirectory + objInfo.Name)
File.Delete(ff)
Else
Dim destdirectory As String = ftempDirectory
Dim ff As String = files(i)
fileToDelete = ff
File.Move(ff, destdirectory + objInfo.Name)
File.Delete(ff)
End If
End If
Continue For
End If
Dim filedate As String = objInfo.Name.Remove(20)
filedate = filedate.Remove(7, 5)
Dim tempDirectory As String = String.Empty
tempDirectory = "M:\Archive\DataE\" + filedate & "\"
If Not Directory.Exists(tempDirectory) Then
Directory.CreateDirectory(tempDirectory)
Dim destdirectory As String = tempDirectory
Dim ff As String = files(i)
fileToDelete = ff
File.Move(ff, destdirectory + objInfo.Name)
File.Delete(ff)
Else
Dim destdirectory As String = tempDirectory
Dim ff As String = files(i)
fileToDelete = ff
File.Move(ff, destdirectory + objInfo.Name)
File.Delete(ff)
End If
Catch ex As Exception
If ex.Message.Contains("already exists") Then
File.Delete(fileToDelete)
Console.WriteLine("DELETING OLD FILE " & fileToDelete)
End If
Continue For
End Try
Next
Next
End Sub
Not sure if the logic makes sense but basically it searches all subfolders for files. Strips the filename to get the date and name which indicates where the file should go. Use the date to create a folder in the destination directory and move files accordingly. If someone can help get started or propose a better way to do this I would really appreciate it.
Not looking too closely (indeed, hardly at all) at your .NET code, it looks like you want to find all of the files in or below a given directory, extract a string from a fixed position in the filename to use as a destination directory, and then move each file to that directory. If that is indeed what you are trying to do, it is fairly simple. To move each file in or below the directory /p/a/t/h to /path2/xxx where xxx is taken from positions 7 to 10 in the file name (I selected the indexes 7 and 10 randomly), just do:
find /p/a/t/h -type f -exec sh -c 'd="/path2/${0:7:3}";
mkdir -p "$d"; mv -i "$0" "$d"' {} \;
The -i flag to mv will cause an interactive prompt if you are overwriting any files, and is here as a safety catch to help prevent the unwary from blowing away files. (But you, the reader, would never execute any code that you don't fully understand, so this is not necessary!) You may want to replace it with a -f or just remove it. Also note that the double quotes are only necessary if your filenames are pathological. (For example, if they contain whitespace.)