I am working on a program where I need the user to select two files from an OpenFileDialog. I don't want to hardcode the file names or paths into the program. I need the contents of these files to display into two columns in a List Box.
So far I have the following code:
OpenFileDialog.ShowDialog()
OpenFileDialog.Filter = "Text Files(.txt)|*.txt"
OpenFileDialog.Title = "Open A Text File"
OpenFileDialog.Multiselect = True
Dim FileArray(1) As String
Dim objreader As New System.IO.StreamReader(OpenFileDialog.FileName)
Dim i = 0
ListBox1.Items.Clear()
ListBox1.Items.Add("Name" & Space$(40) & "ID Number")
Do While objreader.Peek() <> -1
If OpenFileDialog.FileNames.Length = 5 Then
FileArray(0) = objreader.ReadLine & vbCr
Else
FileArray(1) = objreader.ReadLine & vbCr
End If
ListBox1.Items.Add(FileArray(0) & Space$(40) & FileArray(1))
Loop
What I think is happening is the first selected file, 'Names.txt' is being fed into FileArray(0) (because the length of the file name is 5 characters), and then being populated into the correct column in the list box.
However, as it loops a second time, the second file, 'IDNumbers.txt', is read and populated into FileArray(1) (because it fails the 'If') and is overwriting the first array in the list box.
My question is how can I load each file into its own element in my FileArray(1), so I can load them correctly into the ListBox and later manipulate the data?
Related
Good Day,
I am struggling to show empty string value in the data validation list that gets exported to the excel file. I have an array of values that I get from different Lookup tables (one for each valid column). Often some of these lookups will have an empty string value. I can see during debugging that the Empty value does appear in the Results view of the Validation list. But when the excel gets generated, the empty value disappears from the validation list. I followed advise to ensure the empty value appears on top (https://www.thespreadsheetguru.com/blog/blank-value-data-validation-list-excel) but still no luck. Would appreciate any advise here. (Note: we need to have the option to select empty "" string value from the list in exported excel.)
Dim oList_Validation = ws.DataValidations.AddListValidation(strCOlName & "3:" & strCOlName & ValToRow.ToString)
oList_Validation.ShowErrorMessage = True
oList_Validation.ErrorStyle = OfficeOpenXml.DataValidation.ExcelDataValidationWarningStyle.warning
oList_Validation.ErrorTitle = "Error Occurred!!"
oList_Validation.[Error] = "Please select a valid Codelist from drop-down..." & vbCrLf & "Click Cancel to re-set original value."
oList_Validation.ShowInputMessage = True
oList_Validation.Prompt = "Please select a Codelist from the drop-down list..."
oList_Validation.PromptTitle = "Custom Validation List"
Dim oCLMembers = CodeListInfo.ToArray()
Dim oNullCLItem = oCLMembers.Any(Function(a) a.Name.Equals(""))
'Code to add empty string as first value in List
If oNullCLItem = True Then
oList_Validation.Formula.Values.Add("")
End If
For Each CLChild In oCLMembers
oList_Validation.Formula.Values.Add(CLChild.Name)
Next
oList_Validation.AllowBlank = True
I am adding different arrays of strings to a RichTextBox and I want to insert pictures too. I searched for a method and they all say Paste it. I tried that but it doesn't work in a loop.
Dim df As DataFormats.Format = DataFormats.GetFormat(DataFormats.Bitmap)
for i as integer = 0 to 50
RTF1.text = RTF1.text & arr1(i) & arr2(i) & vbnewline
Dim bmp As New Bitmap(picarr(i))
Clipboard.SetImage(bmp)
RTF1.Paste(df)
next i
I also tried SendKeys because when I press Ctrl+V, it pastes the picture. Also, I tried to exit the loop and it pastes the last image only.
Every time you set the RichTextBox.Text property, you lose all the RTF data it previously contained (including formatting, images, etc.) and you're only maintaining the plain text (because of = RTF1.Text & ...).
Instead, use the AppendText() method like this:
Dim df As DataFormats.Format = DataFormats.GetFormat(DataFormats.Bitmap)
For i As Integer = 0 To 50
RTF1.AppendText(arr1(i) & arr2(i) & vbNewLine)
Using bmp As New Bitmap(picarr(i))
Clipboard.SetImage(bmp)
End Using
RTF1.Paste(df)
Next
I have a big table in ms-word that contains 85 contentcontrols (combo boxes). I want to change the content using a vba loop (see below). It takes longer than one minute for it to complete...
Are there other options?
Private Sub Btn_Clear1_Click()
Dim a
Dim c As ContentControl
a = FindTable(ActiveDocument.Name, "myTableName")(1) 'returns an array(Long) with number of table found
For Each c In ActiveDocument.Tables(a).Range.ContentControls
c.Range.text = "MY CHANGED TEXT"
Next c
End Sub
Thanks in advance for any hint!
Here, turning off screenupdating reduces the time from about 6 seconds to less than 1 second. e.g.
On Error Goto turnscreenon
Application.Screenupdating = False
For Each c In ActiveDocument.Tables(a).Range.ContentControls
c.Range.text = "MY CHANGED TEXT"
Next c
turnscreenon:
Application.Screenupdating = True
That may only work on the Windows version of Word.
If you know exactly how many combo boxes there are going to be, you could consider creating a custom xml part containing an array of XML Elements to contain the values. Map each content control to one of those elements. Then instead of writing the values to the content control ranges, write them to the XML Part and let Word do the work. That works almost instantaneously here.
e.g. in a simple scenario where you just have those 85 content controls in the table, you could set up the Custom XML Part like this (I leave you to write any code that you need to delete old versions). You should only need to run this once.
Sub createCxpAndLink()
' You should choose your own Uri
Const myNamespaceUri As String = "mycbcs"
Dim a
Dim i As Long
Dim s As String
Dim cxp As Office.CustomXMLPart
With ActiveDocument
a = FindTable(.Name, "myTableName")(1)
s = ""
s = s & "<?xml version='1.0' encoding='UTF-8'?>" & vbCrLf
s = s & "<cbcs xmlns='" & myNamespaceUri & "'>" & vbCrLf
For i = 1 To .Tables(a).Range.ContentControls.Count
s = s & " <cbc/>" & vbCrLf
Next
s = s & "</cbcs>"
Set cxp = .CustomXMLParts.Add(s)
With .Tables(a).Range.ContentControls
For i = 1 To .Count
.Item(i).XMLMapping.SetMapping "/x:cbcs[1]/x:cbc[" & Trim(CStr(i)) & "]", "xmlns:x='" & myNamespaceUri & "'", cxp
Next
End With
Set cxp = Nothing
End With
End Sub
Then to update the contents you need something like this
Sub testsetxml()
Const myNamespaceUri As String = "mycbcs"
Dim i As Long
'our start time...
Debug.Print Now
With ActiveDocument.CustomXMLParts.SelectByNamespace(myNamespaceUri)(1)
For i = 1 To 85
.SelectNodes("/ns0:cbcs[1]/ns0:cbc[" & Trim(CStr(i)) & "]")(1).Text = "my changed text "
' or if you want to put different texts in different controls, you can test using e.g.
.SelectNodes("/ns0:cbcs[1]/ns0:cbc[" & Trim(CStr(i)) & "]")(1).Text = "my changed text " & Cstr(i)
Next
End With
'our end time...
Debug.Print Now
End Sub
(NB you cannot do it by mapping all the controls to a single XML element because then all the dropdowns will all be updated to the same value whenever you change the value of one of them.)
Apologies for any typos - I've changed the code to be more in line with what you have already and have not tested the changes.
I'm trying to create a little program thats introduce some prefixes into the name of the files that found at a folder.
The names of files are listed at a Listbox1 and the prefixes are choosed at a several Comboboxes.
This names of the Listbox1 with the choosed prefixes of the Comboboxes are moved to a Listbox2 pressing a buttom ">>>".
When all of new names are ready at this Listbox2 will be press a buttom "Rename" and the names of files at the folder will be changed according fixed at the Listbox2.
All of the Userform is already programmed. I have just problems to build the code for the buttom "Rename".
In others Words, taking the stipulate names of the Listbox2 and changing the names at the respective files showed before at the Listbox1.
How i can read the new names of files from a Listbox and introduce to the respective name of file?
Userform Screenshot
Code:
Sub cmdMoveSelLeft_Click()
'Variable Declaration
Dim iCnt As Integer
'Move Selected Items from Listbox1 to Listbox2
For iCnt = 0 To Me.ListNewFiles.ListCount - 1
If Me.ListNewFiles.Selected(iCnt) = True Then
Dim changedName As String
changedName = Me.ComboBoxKategorie.Value + "_" + Me.ComboBoxTyp.Value + "_" + Me.ListNewFiles.List(iCnt)
Me.ListChangedFiles.AddItem changedName
End If
Next
For iCnt = Me.ListNewFiles.ListCount - 1 To 0 Step -1
If Me.ListNewFiles.Selected(iCnt) = True Then
Me.ListNewFiles.RemoveItem iCnt
End If
Next
ComboBoxKategorie = ""
ComboBoxTyp = ""
TextBoxEXX = ""
TextBoxUX = ""
TextBoxTrakt = ""
TextBoxGebaude = ""
TextBoxSpecific = ""
Sub cmdRename_Click()
Dim Msg = 'Möchten Sie fortfahern?'
Response = MsgBox(Msg, Style, Title, Help, Ctxt)
If Response = vbYes Then ' User chose Yes.
~?????????????~
MsgBox "Die Namen sind angepasst" & vbCrLf
Unload Me
End If
End Sub
Use the Name keyword like
Name "C:\Post IN\BEISPEIL_SAN_SP_U2" As "C:\Post IN\AUS_BPH_BEISPEIL_SAN_SP_U2"
Of course you won't use string literals like that, but I can't tell where you have the old name and the new name. Generally, the syntax is
Name "FullPathOfExistingName" As "FullPathOfNewName"
I have a simple form with 10 or more buttons.
These are named Button1, Button2 etc.
I want the user to save a simple txt file for each button text in a folder. Why? Well Each end user will want to have different names for each button from the next user who will use the form. Each user will need to set his own text description to suit his needs. (once at set up) So in a folder location I have... Button1.txt, Button2.txt etc each with a default starting text.
On loading the form, I want to loop through the txt files and add the user edited names to each of the buttons.
I can get this to work long hand...doing it one at a time,
but I know I should be able to loop through simply...
I have tried several variations on this
For i = 1 To 10
Dim FILE_NAME As String = "C:\QuickButtons\ButtonTxt\Button" & i & ".txt"
If System.IO.File.Exists(FILE_NAME) = True Then
Dim objReader As New System.IO.StreamReader(FILE_NAME)
Me.Controls("Button" & i).Text = objReader.ReadToEnd
objReader.Close()
Next
I keep getting "Object reference not set to an instance of an object."
For someone out there this is an easy one... if I had hair, I would be pulling it out!
So I send you many thanks in advance.
The problem is most likely here:
Me.Controls("Button" & i).Text = objReader.ReadToEnd
This will only succeed if the buttons are contained directly by the Form. If they are in a different container, like a Panel, then it would fail.
One solution is to search for the control like this:
For i As Integer = 1 To 10
Dim FILE_NAME As String = "C:\QuickButtons\ButtonTxt\Button" & i & ".txt"
If System.IO.File.Exists(FILE_NAME) Then
Dim matches() As Control = Me.Controls.Find("Button" & i, True)
If matches.Length > 0 AndAlso TypeOf matches(0) Is Button Then
Dim btn As Button = DirectCast(matches(0), Button)
btn.Text = System.IO.File.ReadAllText(FILE_NAME)
End If
End If
Next
A better approach would be to have a single XML file, where you would have all of your custom labels. Something like this:
<labels>
<button index="0" name="button1" />
<button index="1" name="button2" />
...
</labels>
Depending on your design, this may be inside your app.config, or a standalone file.