Working on a management program for basic files and text.
Now, so far the program is saving information from multiple textboxes into an .xml file correctly.
My problem is where I need to load saved files back into Textboxes.
Here is another thread I made to Microsoft explaining my issue;
Right, so the code I currently have and use;
Private Sub Objectlist1_ItemActivate(sender As Object, e As EventArgs) Handles Objectlist1.ItemActivate
Caseworker.Show()
Me.Objectlist1.MultiSelect = False
Dim selectedListViewItem As String
selectedListViewItem = Me.Objectlist1.SelectedItems.Item(0).ToString
If (IO.File.Exists(selectedListViewItem + "C:\Users\USER\Desktop\Testfolder-data")) Then
Dim document As XmlReader = New XmlTextReader(selectedListViewItem + "C:\Users\USER\Desktop\Testfolder-data")
While (document.Read())
Dim type = document.NodeType
If (type = XmlNodeType.Element) Then
If (document.Name = "Person") Then
Caseworker.Pholderbox.Text = document.ReadInnerXml.ToString()
End If
If (document.Name = "Driver") Then
Caseworker.Driverbox.Text = document.ReadInnerXml.ToString()
Problem here is that I want to be able to click a file in the Listview called "Objectlist1" and the program loads the xml file - Instead of directing the program to One file
As such
If (IO.File.Exists("MyXML.xml")) Then
Dim document As XmlReader = New XmlTextReader("MyXML.xml)
Apparently there is this variable out there that would be perfect for my issue, but I have looked for it for 2 working days and not been able to track it down.
If there is another stuff I need to add to make this thing work, I appreciate any help you can provide.
Am I far off here guys?
A few things:
You need the full path to the XMLFile, not just its name. You could do it like this (warning: untested):
const string basepath= #"C:\Users\USER\Desktop\Testfolder-data"
xmlpath = IO.Path.Combine(basepath, Objectlist1.SelectedItems.Item(0).Text)
If(IO.File.Exists(xmlpath))
Instead of multiple Ifs, I would recommend
switch(document.Name)
{
Case "Person":
Caseworker.Pholderbox.Text=...
break;
Case "Driver":
...
}
If you rename "Pholderbox" to "Personbox", you could spare the entire If/switch and simply do something like:
var textbox = document.name + "box";
(TextBox)Caseworker.Controls[textbox].Text=document.InnerText;
Hope this gets you going.
Related
Using DocumentFormat.OpenXML, I am trying to add a custom property to a Word document and then later read the property. The following code "appears" to do just that:
Dim os As OpenSettings = New OpenSettings() With {
.AutoSave = False
}
Dim propVal As String = "Test Value"
Using doc As WordprocessingDocument = WordprocessingDocument.Open(filename, True, os)
Dim cPart As CustomFilePropertiesPart = doc.CustomFilePropertiesPart
If cPart Is Nothing Then
cPart = doc.AddCustomFilePropertiesPart
cPart.Properties = New DocumentFormat.OpenXml.CustomProperties.Properties()
End If
Dim cPart As CustomFilePropertiesPart = doc.CustomFilePropertiesPart
Dim cProps As Properties = cPart.Properties
For Each prop As CustomDocumentProperty In cProps
If prop.Name = "TranscriptID" Then
prop.Remove()
Exit For
End If
Next
Dim newProp As CustomDocumentProperty = New CustomDocumentProperty() With {
.Name = "TranscriptID"
}
newProp.VTBString = New VTBString(propVal)
newProp.FormatId = "{D5CDD505-2E9C-101B-9397-08002B2CF9AE}"
cProps.AppendChild(newProp)
Dim pid As Integer = 2
For Each item As CustomDocumentProperty In cProps
item.PropertyId = pid
pid += 1
Next
cProps.Save()
End Using
This code is modeled after code found here:
https://learn.microsoft.com/en-us/office/open-xml/how-to-set-a-custom-property-in-a-word-processing-document
It appears to work in this scenario:
Execute code from above.
Execute code from above again.
At #2 I expect to find the CustomFilePropertiesPart and the property value and my expectation is met.
The problem appears in this scenario:
Execute code from above.
Open document using Microsoft Word, save and close.
Execute code from above again.
What happens in this scenario is that the CustomFilePropertiesPart is missing, whereas it should be found. It is as if Microsoft Word does not successfully read this object, so when the document is save, the object is lost. This suggests to me that there is something that there is something wrong with my code. If you can see what it is, or if you have a comparable working example that I could compare it with, I would appreciate hearing from you. I feel like I correctly followed the Microsoft example, but obviously I did not and I am having trouble seeing where I departed. Thanks.
OK, I found this wonderful tool called the Office Productivity Tool. It has a code generation feature, so I was able to compare what I was doing with what Word does. Basically the problem was with setting the property value. This snippet does the trick:
Dim cProps As Properties = cPart.Properties
Dim val As DocumentFormat.OpenXml.VariantTypes.VTLPWSTR = New DocumentFormat.OpenXml.VariantTypes.VTLPWSTR
val.Text = tr.ID.ToString
Dim newProp As CustomDocumentProperty = New CustomDocumentProperty() With {
.Name = "TranscriptID",
.FormatId = "{D5CDD505-2E9C-101B-9397-08002B2CF9AE}"
}
newProp.Append(val)
cProps.AppendChild(newProp)
I am trying to extract an application resource from My.Resources.FILE
I have discovered how to do this with DLL & EXE files, but I still need help with the code for extracting PNG & ICO files.
Other file types also. (If possible)
Here is my current code that works with DLL & EXE files.
Dim File01 As System.IO.FileStream = New System.IO.FileStream("C:\Users\" + Environment.UserName + "\Desktop\" + "SAMPLE.EXE", IO.FileMode.Create)
File01.Write(My.Resources.SAMPLE, 0, My.Resources.SAMPLE.Length)
File01.Close()
First things first, the code you have is bad. When using My.Resources, every time you use a property, you extract a new copy of the data. That means that your second line is getting the data to write twice, with the second time being only to get its length. At the very least, you should be getting the data only once and assigning it to a variable, then using that variable twice. You should also be using a Using statement to create and destroy the FileStream. Even better though, just call File.WriteAllBytes, which means that you don't have to create your own FileStream or know the length of the data to write. You should also not be constructing the file path that way.
Dim filePath = Path.Combine(My.Computer.FileSystem.SpecialDirectories.Desktop, "SAMPLE.EXE")
File.WriteAllBytes(filePath, My.Resources.SAMPLE)
As for your question, the important thing to understand here is that it really has nothing to do with resources. The question is really how to save data of any particular type and that is something that you can look up for yourself. When you get the value of a property from My.Resources, the type of the data you get will depend on the type of the file you embedded in first place. In the case of a binary file, e.g. DLL or EXE, you will get back a Byte array and so you save that data to a file in the same way as you would any other Byte array. In the case of an image file, e.g. PNG, you will get back an Image object, so you save that like you would any other Image object, e.g.
Dim filePath = Path.Combine(My.Computer.FileSystem.SpecialDirectories.Desktop, "PICTURE.PNG")
Using picture = My.Resources.PICTURE
picture.Save(filePath, picture.RawFormat)
End Using
For an ICO file you will get back an Icon object. I'll leave it to you to research how to save an Icon object to a file.
EDIT:
It's important to identify what the actual problem is that you're trying to solve. You can obviously get an object from My.Resources so that is not the problem. You need to determine what type that object is and determine how to save an object of that type. How to do that will be the same no matter where that object comes from, so the resources part is irrelevant. Think about what it is that you have to do and write a method to do it, then call that method.
In your original case, you could start like this:
Dim data = My.Resources.SAMPLE
Once you have written that - even as you write it - Intellisense will tell you that the data is a Byte array. Your actual problem is now how to save a Byte array to a file, so write a method that does that:
Private Sub SaveToFile(data As Byte(), filePath As String)
'...
End Sub
You can now which you want to do first: write code to call that method as appropriate for your current scenario or write the implementation of the method. There are various specific ways to save binary data, i.e. a Byte array, to a file but, as I said, the simplest is File.WriteAllBytes:
Private Sub SaveToFile(data As Byte(), filePath As String)
File.WriteAllBytes(filePath, data)
End Sub
As for calling the method, you need to data, which you already have, and the file path:
Dim data = My.Resources.SAMPLE
Dim folderPath = My.Computer.FileSystem.SpecialDirectories.Desktop
Dim fileName = "SAMPLE.EXE"
Dim filePath = Path.Combine(folderPath, fileName)
SaveToFile(data, filePath)
Simple enough. You need to follow the same steps for any other resource. If you embedded a PNG file then you would find that the data is an Image object or, more specifically, a Bitmap. Your task is then to learn how to save such an object to a file. It shouldn't take you long to find out that the Image class has its own Save method, so you would use that in your method:
Private Sub SaveToFile(data As Image, filePath As String)
data.Save(filePath, data.RawFormat)
End Sub
The code to call the method is basically as before, with the exception that an image object needs to be disposed when you're done with it:
Dim data = My.Resources.PICTURE
Dim folderPath = My.Computer.FileSystem.SpecialDirectories.Desktop
Dim fileName = "SAMPLE.EXE"
Dim filePath = Path.Combine(folderPath, fileName)
SaveToFile(data, filePath)
data.Dispose()
The proper way to create and dispose an object in a narrow scope like this is with a Using block:
Dim folderPath = My.Computer.FileSystem.SpecialDirectories.Desktop
Dim fileName = "SAMPLE.EXE"
Dim filePath = Path.Combine(folderPath, fileName)
Using data = My.Resources.PICTURE
SaveToFile(data, filePath)
End Using
Now it is up to you to carry out the same steps for an ICO file. If you are a hands on learner then get your hands on.
So I am creating a program that needs to be able to read line by line from a .cfg (config) file, it can open it happily; here is the code:
OpenConfig.ShowDialog()
file = OpenConfig.FileName()
fileReader()
However when it tries to read the file, using this code:
Function fileReader()
Dim reader As New StreamReader(file)
Dim vLb As ListBox = shopTabs.SelectedTab.Controls.Item(10) 'Listbox Variable
For i = 0 To reader.Peek
textline(i) = reader.ReadLine()
vLb.Items.Add(i)
Next
Return True
End Function
It throws an exception at the line:
textline(i) = reader.ReadLine()
Any help would be greatly appreciated as I can't work out why it does so.
Your code could be simplified into the following code:
Using openConfig As New OpenFileDialog()
If openConfig.ShowDialog(Me) = DialogResult.OK Then
For Each s As String In File.ReadAllLines(openConfig.FileName)
ListBox1.Items.Add(s)
Next
End If
End Using
As I commented, your code does some things that are highly questionable and undoubtedly difficult to maintain, such as referencing a control by the index property.
I suspect that your project would benefit from using UserControls too, since I'm guessing you have the same controls placed in every tab (a ListBox is always control index #10?).
I'm having issues with reporting a Crystal Reports file to PDF format. I've looked at all the other questions here regarding the issue but none of them seem to solve mine.
Here is my code:
Public Sub ExportReportToPDF(ReportObject As CRAXDRT.Report, ByVal filename As String, ByVal ReportTitle As String)
Dim objExportOptions As CRAXDRT.ExportOptions
ReportObject.ReportTitle = ReportTitle
With ReportObject
.EnableParameterPrompting = False
.MorePrintEngineErrorMessages = True
End With
Set objExportOptions = ReportObject.ExportOptions
With objExportOptions
.DestinationType = crEDTDiskFile
.DiskFileName = filename
'.FormatType = crEFTExcel80Tabular
'.FormatType = crEFTCommaSeparatedValues
'.FormatType = crEFTExcel80
'.FormatType = crEFTHTML32Standard
'.FormatType = crEFTHTML40
.FormatType = crEFTPortableDocFormat
'.FormatType = crEFTRichText
'.FormatType = crEFTText
'.FormatType = crEFTWordForWindows
End With
ReportObject.Export False
End Sub
Now, I've left the other options besides PDF in there just to show them, they're all commented out obviously, but if I try any of the other formats, it exports just fine. The only format that doesn't export is PDF. It gives me the error:
Run-time error '-2147190908 (80047784)':
Failed to Export the Report.
When I click Debug it highlights on the ReportObject.Export False line.
On another note, if I make it so the user chooses the options, I can select PDF and it still gives me the same error. Thanks for the help.
(Thanks to AVD for the coding found here How to Export to a PDF file in Crystal Report?).
EDIT: After going through Phillipe's responses, I was stepping through my code and noticed that after it assigned crEFTPortableDocFormat to FormatType, it auto assigns "UXFPDF.DLL" to FormatDllName. Maybe this is my problem, does anyone know how to fix this? I tried just renaming crxf_pdf.dll and also u2fpdf.dll (the one that was for 8.0 which I originally had) but that didn't work.
EDIT: Another find is that when I enable the Export Option in CRViewer91 (which shows the report correctly) and I try and export this to a pdf via this method, it does not error. However, it saves a file that is corrupted pretty much and cannot be opened.
EDIT: More research. The CRViewer91 doesn't appear to be able to export any format successfully. RTF and TXT return a blank document, RPT errors when trying to open.
EDIT: I think part of my problem may be that I've been using the 8.0 CRAXRT.DLL when what I actually need is the 9.0 one. I've found the one for 9.0, now how do I make it use this instead of the old one?
I'm not exactly sure what was causing all the errors, however, I've fixed it via basically starting a new project from scratch and incorporating only the necessary references and components. I know one problem I had (which caused a TLV error) was that the CRAXDRT.dll for CR9 was in the Windows\system32 directory, and even though it was referencing that .dll, it needed to reference it from the Program Files\Common Files\CrystalDecision... directory where all the other .dlls for CR9 are located.
There was also a minor code change that needed to be done, here is the finalized code that works for exporting mine to PDF.
Public Sub ExportReportToPDF(ReportObject As CRAXDRT.Report, ByVal filename As String, ByVal ReportTitle As String)
Dim FormatDLLName As String
ReportObject.ReportTitle = ReportTitle
With ReportObject
.EnableParameterPrompting = False
.MorePrintEngineErrorMessages = True
End With
With ReportObject.ExportOptions
.DestinationType = crEDTDiskFile
.DiskFileName = filename
'.FormatType = crEFTExcel80Tabular
'.FormatType = crEFTCommaSeparatedValues
'.FormatType = crEFTExcel80
'.FormatType = crEFTHTML32Standard
'.FormatType = crEFTHTML40
.FormatType = crEFTPortableDocFormat
'.FormatType = crEFTRichText
'.FormatType = crEFTText
'.FormatType = crEFTWordForWindows
End With
ReportObject.Export False
End Sub
I left the commented out FormatTypes in there for anyone else who finds this code useful. Phillipe, if you would like to "answer" this somehow like this, I would love to give you some rep for all of your help that you provided however. I don't have enough rep to just upvote your stuff so.
Thanks for all your help either way.
Dan
I guess that 'filename' value does not work, either because the folder does not exist / the file name is not valid, or because you do not have the corresponding rights to create a file under this folder.
Could you try the code with some basic parameter like 'filename = "c:\test.pdf"'?
My last guess: the possibility to export to pdf format needs a specific dll file under the crystal folder (does not need to be registered but needs to be here). Do you have the crxf_pdf.dll file ?
EDIT:
My last question: are you able to expor tto PDF from the Crystal GUI?
Here is a list of the crystal report files that must be distributed with a VB app, if of any help: export capabilities seem to be linked to the crxf_*.dll files
CRAnalyzer.dll
craxdrt.dll
crdb_ado.dll
crdeploy.reg
crheapalloc.dll
crqe.dll
crtowords_en.dll
crtslv.dll
crviewer.dll
crxf_html.dll
crxf_pdf.dll
crxf_rtf.dll
crxf_wordw.dll
crxf_xls.dll
cxlibw-1-6.dll
dbghelp.dll
exlate32.dll
ExportModeller.dll
GDIPLUS.DLL
Implode.dll
keycode.dll
msvcrt.dll
pageObjectModel.dll
querybuilder.dll
ReportRenderer.dll
riched20.dll
sscdlg.dll
sscsdk80.dll
u252000.dll
u25dts.dll
u25samp1.dll
u2dapp.dll
u2ddisk.dll
u2dmapi.dll
u2dpost.dll
u2fcr.dll
u2frdef.dll
u2frec.dll
u2fsepv.dll
u2ftext.dll
u2fxml.dll
u2l2000.dll
u2lcom.dll
u2ldts.dll
u2lexch.dll
u2lfinra.dll
ufmanager.dll
usp10.dll
webReporting.dll
Am learning arrays at the moment and I have the below piece of code that goes through drive C: and displays the files in in a list box.
I want to try and expand it to use array.sort so that it gets the files, puts them into an array, and then I can sort by filename or file size. I have been rattling my brain over this - as to how do I put the files into an array.
Would like an explanation if possible as more interested in learning it rather than the answer.
Thanks!
Private Sub btnclick_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnclick.Click
Call Clearlist()
Dim strFilesinfo As System.IO.FileInfo
Dim strlength As Double = 0
Dim strname As String = ""
For Each strFiles As String In My.Computer.FileSystem.GetFiles("c:\")
strFilesinfo = My.Computer.FileSystem.GetFileInfo(strFiles)
strlength = strFilesinfo.Length
strname = strFilesinfo.Name
lstData.Items.Add(strname & " " & strlength.ToString("N0"))
Next
End Sub
End Class
To allow the data to be sortable, you'd need to be displaying something that could treat that information separately (i.e. a class or structure). You might also find that a different type of control, such as a DataGridView might be easier to get to grips with.
The .Net framework does define an interface, IBindingList which collections can implement to show that they report, amongst other things, sorting.
I'm providing this as a sample for learning purposes but it should not be used as-is. Getting every file from the entire C:\ should not be done like this. Aside from the performance issues there are windows security limitations that won't actually let you do this.
The FileList being populated here is getting just the TopDirectoryOnly. If you change that input to "AllDirectories" it will get all the subdirectories but it will fail as I stated before.
Dim path As String = "C:\"
Dim dir As New System.IO.DirectoryInfo(path)
Dim fileList = dir.GetFiles("*.*", IO.SearchOption.TopDirectoryOnly)
Dim fileSort = (From file In fileList _
Order By file.Name _
Select file.Name, file.Length).ToList
For Each file In fileSort
With file
lstData.Items.Add(String.Format("{0} {1}", .Name, .Length.ToString("N0")))
End With
Next file
Just change the Order By in the LINQ query to change how the sorting is done. There are many other ways to do the sorting but LINQ will handle it for you with very little code.