Is there a way to set the image from one PictureBox object to another? For example:
pictureboxA1.image = pictureboxB1.image
pictureboxA2.image = pictureboxB2.image
pictureboxA3.image = pictureboxB3.image
I did a similar thing with TextBox controls, but this code isn't working for me:
For i = 0 To 2
Me.Controls("picturebox" + "A" & i + 1).image = Me.Controls("picturebox" + "B" & i + 1).image
Next i
When I run this, I get an error stating .image is not a member of 'System.Windows.Forms.Control'.
i know that is pictureboxA1.image = pictureboxB1.image.
but if i try like this
For i = 0 To 2
Me.Controls("picturebox" + "A" & i + 1).image = Me.Controls("picturebox" + "B" & i + 1).image
Next i
it says that image is not a member of controls.
because i have to do this pictureboxA1.image = pictureboxB1.image, 21 times.
like
pictureboxA1, pictureboxA2, ... 3, 4, 5, 6, 7 until 21.
and if i do it like this
pictureboxA1.image = pictureboxB1.image
i have to right the code 21 times and if i do it with for its just one time xD.
and i tryed .picture it says the same thing
Sorry, I should have seen this sooner. You need to set the control to a PictureBox in order for it to recognize the property. I think. Something like this might work. I don't have access to a PictureBox control, so it's a guess:
Dim pic as PictureBox
For i = 0 To 2
set pic = Me.Controls("picturebox" + "A" & i + 1)
pic.image = Me.Controls("picturebox" + "B" & i + 1).image
Next i
Related
First post here. Self-taught VBA so I'm always aware that code may not be perfect. Anyway...
Creating a Userform Questionnaire. I don't know how many questions there will be, and I want it to be easy for anyone to add new questions to the form. Idea is to have the questions listed on a Sheet so that as new questions are added, the userbox will resize accordingly and add in all the questions.
Doing this was no problem:
Public Sub UserForm_Activate()
QuestionsCount = Application.WorksheetFunction.CountA(Sheets("QuestionData").Range("A:A")) - 1
ResultsCount = Application.WorksheetFunction.CountA(Sheets("QuestionData").Range("B:B")) - 1
DepartmentCount = Application.WorksheetFunction.CountA(Sheets("QuestionData").Range("C:C")) - 1
QuestionForm1.ScrollHeight = (QuestionsCount) * 70
QuestionForm1.Width = 258
CommandButton1.Top = (QuestionsCount - 1) * 70
CommandButton1.Left = 42
CommandButton2.Top = (QuestionsCount - 1) * 70
CommandButton2.Left = 132
Dim i As Integer
Dim QQ(1 To 100) As MSForms.Control
Dim QA(1 To 100) As MSForms.Control
For i = 5 To QuestionsCount
Set QQ(i) = QuestionForm1.Controls.Add("Forms.Label.1")
Set QA(i) = QuestionForm1.Controls.Add("Forms.ComboBox.1")
With QQ(i)
.Caption = Sheets("QuestionData").Range("A" & (i + 1))
.Width = 84
.Top = i * 58
.Left = 24
.Name = "Label" & i
End With
With QA(i)
.RowSource = "QuestionData!B2:B" & ResultsCount + 1
.Width = 96
.Top = i * 58
.Left = 138
.Name = "Combo" & i
.Value = ""
End With
Next i
End Sub
Userform is created and all the questions I want are there (positioning of the command buttons isn't great, I know, will fix this soon)
The only problem is taking the values. The answers are in a ComboBox, the user will select the answers they want and click the Submit button. The idea was to then take the values from each comboBox and put them into another sheet.
The issue I'm having is that the global variables seem to disappear at the end of the sub. So when the user inserts their answers and clicks Submit, the macro tries to take values that aren't there.
What are the names of the added ComboBoxes? Where are their values stored? Is there a way to not End Sub so that the values stay as Global Variables? Any other ideas on what to do?
Any help would be appreciated...hopefully I've explained myself well!
thanks in advance!!
You've named your comboboxes using .Name = "Combo" & i.
So you could create a routine that runs on pressing a SUBMIT button or similar that reads the values with:
QuestionForm1.Controls("Combo5").Value
You could also set this up as a loop to build an array with:
Private Sub CommandButton1_Click()
ResultsCount = Application.WorksheetFunction.CountA(Sheets("QuestionData").Range("B:B")) - 1
Dim chosenvalue(100)
For i = 5 To ResultsCount
chosenvalue(i) = QuestionForm1.Controls("Combo" & i).Value
Debug.Print "Button " & i & " set to " & chosenvalue(i)
Next
End Sub
I am trying to make a program that searches for specific content in cells for excel:
rows represent hours of the day from 00:00 to 23:00
columns represent a day of the month
The following code matches the input of the user to the content of the cells either by using the name. It can also add or skip a time interval for the event
However the following code always runs the instructions under Else even if the user inputs 2 numeric values for the 2 param fields. Some help would be appreciated:
pNume = paramNume
aux = ""
aux1 = paramHBegin - 1
aux2 = paramHEnd - 1
If IsNumeric(paramHBegin) And IsNumeric(paramHEnd) Then
For i = 1 To 31
For j = aux1 To aux2
If Cells(i + 1, j + 1) Like pNume & "*" Or Cells(i + 1, j + 1) Like "*" & pNume & "*" _
Or Cells(i + 1, j + 1) Like "*" & pNume Then
aux = aux + Cells(i + 1, j + 1) + " la ora " + CStr(i) + vbCrLf
End If
Next j
Next i
Else
For i = 1 To 31
For j = 1 To 24
If Cells(i + 1, j + 1) Like pNume & "*" Or Cells(i + 1, j + 1) Like "*" & pNume & "*" _
Or Cells(i + 1, j + 1) Like "*" & pNume Then
aux = aux + Cells(i + 1, j + 1) + " la ora " + CStr(i) + vbCrLf
End If
Next j
Next i
End If
displayInfo.Text = aux
This statement
If IsNumeric(paramHBegin) And IsNumeric(paramHEnd) Then
will only be true if both of the values you pass are numeric. But you wrote that "However the following code always runs the instructions under Else even if the user inputs 2 numeric values for the 2 param fields."
Assuming paramHBegin and paramHEnd are defined as strings, the only way I can see that happening is for one or both of the values having a character that isn't numeric. In Excel 2013 IsNumeric ignores carriage returns, tabs and spaces so they aren't the cause of the problem. If they are defined as objects, then you should specify the correct property of those objects.
Sorry I can't try it myself, but try something like this:
If IsNumeric(paramHBegin.Text) And IsNumeric(paramHEnd.Text) Then
or this:
If IsNumeric(val(paramHBegin.Text)) And IsNumeric(val(paramHEnd.Text)) Then
I think it's better to handle user inputs right at the input session itself rather then passing everything forward and then trying to handle exceptions
for instance, to force (to some extent) numeric inputs you could place in the UserForm code pane what follows:
Option Explicit
Private Sub paramHBegin_AfterUpdate()
TextBoxValidate Me.paramHBegin
End Sub
Private Sub paramHEnd_AfterUpdate()
TextBoxValidate Me.paramHEnd
End Sub
Private Sub paramNume_AfterUpdate()
TextBoxValidate Me.paramNume
End Sub
Sub TextBoxValidate(ctrl As MSForms.TextBox)
Dim number As Double
Me.CommandButton1.Enabled = False
With ctrl
If Not ValidateText(.text, number) Then
MsgBox "invalid input", vbCritical
.SetFocus
Else
.text = number
Me.CommandButton1.Enabled = True
End If
End With
End Sub
Function ValidateText(text As String, number As Double) As Boolean
On Error Resume Next
number = CDbl(WorksheetFunction.Substitute(text, " ", ""))
ValidateText = IsNumeric(number)
End Function
in essence:
add an AfterUpdate event handler for every relevant TextBox
that event handler would simply pass the validation dues to a specific sub (TextBoxValidate()) where you can put code to handle general TextBox validation environment
for instance I
disabled CommandButton1 button (the "OK" one in my test)
call a function (ValidateText()) for validating the Text property of a TextBox control which would return:
True and the validated number, if the Text property were actually a possible number
False otherwise
if validation result is True:
update the TextBox with the validated number
enable the "OK" Button
if validation result is False:
prompt a message and return the focus to the "invalid" TextBox
of course you can tune all those Subs and Functions to your actual needs like:
checking for specific text formats (with Like operator or - better - with RegEx object)
checking for specific types ( using Clng() or CInt() or CDate() instead of CDbl() in a sort of TryParse() fashion
changing validation rules according to each control type (TextBox rather than ListBox and so on) and property (Text Property rather than Value ...)
Finally
use "&" operator instead of "+" one to concatenate strings
If Cells(i + 1, j + 1) Like pNume & "*" Or Cells(i + 1, j + 1) Like "*" & pNume & "*" _
Or Cells(i + 1, j + 1) Like "*" & pNume Then
can be reduced to:
If Cells(i + 1, j + 1) Like "*" & CStr(pNume) & "*" Then
hope all this can help
I'm currently writing a Who Wants To Be A Millionaire program and I can't seem to figure out a serious error in the code. Specifically the 50/ 50 lifeline. Whenever the correct answer is the first answer in the choices the program crashes. Otherwise if the correct answer is the 2,3 or 4th choice, it works fine.
I really don't know why it does this and my efforts of fixing it has been useless. I'm using an array to hold which choice is the correct choice for each answer.
correctanswer(i)
Dim remove As Integer
Dim remove1 As Integer
start:
remove = CStr(Int(Rnd() * 4))
If remove + 2 = correctanswer(i) + 1 Then
GoTo start
End If
start2:
remove = CStr(Int(Rnd() * 5))
If remove1 + 2 = correctanswer(i) + 1 Then
GoTo Start2
ElseIf remove1 = remove Then
GoTo Start2
End If
Dim r1 As Button
r1 = Me.Controls("cmdanswer" & remove + 1)
r1.Enabled = False
r1.Text = ""
Dim r2 As Button
r2 = Me.Controls("cmdanswer" & remove1 + 1)
r2.Enabled = False
r2.Text = ""
There's an infinite loop whenever remove1 + 2 = correctanswer(i) + 1. It goes back to start2, then continues down to the if statement, then to start2, over and over. The value of remove1 and correctanswer(i) never change.
I have a richTextbox, and a while loop, x = 0, and every time this loop runs, x += 1 till it reaches a certain value.
Heres what I want to happen:
while x <> 10 then
it will say item 0 +1 on a new line, and then item 1 + 1 on the line under it, etc, so you will see all 10 values after.
What happens is, it will change that line into the new value.
My question is: How do I make it put the words on a new line instead?
Here is my code:
While readListItem <> PaymentList.Items.Count
If readListItem > PaymentList.Items.Count Then
readListItem = 0
Exit While
End If
readListItem += 1
MessageBox.Show(readListItem)
resultBox.Text = vbNewLine + PaymentList.Items.Item(readListItem) + " costs " + enteredCost + "." + vbNewLine
End While
readListItem is "x", and that is being iterated by 1 every time the loop runs
PaymentList is my listbox containing an unknown value (the user sets the number of items in this list)
The If if there because, after x = lets say 10, it would add another to x (so now it = 11) and try to print out the 11th item, as it doesnt exist, it crashes. This is to attempt to prevent that. I didnt want to go with a try catch
Try adding the new value instead of replacing the entire value:
resultBox.Text &= Environment.NewLine() & PaymentList.Items.Item(readListItem) + " costs " + enteredCost + "."
The expression &= is equivalent, in this case, to resultBox.Text = resultBox.Text & "...".
And once advice, you can simplify your loop by using this condition:
While readListItem < PaymentList.Items.Count
'...
End While
The following code works, to simply get each line as a line in the listbox.
Reader = IO.File.OpenText(textlocation)
Dim bookmarks() As String = Reader.ReadToEnd.Split(vbNewLine)
Dim i As Integer = 0
Do Until i = bookmarks.Length
lstFavorites.Items.Add(bookmarks(i))
i += 1
Loop
But I don't want every line to go into the text box. I only want the lines that contain the text "Bookmark" to go into the listbox. What can I do to achieve this? I've tried everything I can think of.
Heres some code I tried, I can't see the problem in it, but it seems to just crash my program.
Do Until i = bookmarks.Length
If bookmarks(i).Contains("at") Then
If radBookmarks.Checked Then
If bookmarks(i).Contains("Bookmark") Then
Original = bookmarks(i)
BeginningOfDemoName = Original.Substring(Original.LastIndexOf("(") + 2)
TickWithParenthesis = BeginningOfDemoName.Substring(BeginningOfDemoName.IndexOf(Chr(34)) + 4)
Tick = TickWithParenthesis.Split(" ")(1).Split(")")(0)
DemoName = BeginningOfDemoName.Split(Chr(34))(0)
ToList = DemoName + " at " + Tick
lstFavorites.Items.Add(ToList)
i += 1
Else
i += 1
End If
ElseIf radEverything.Checked Then
Original = bookmarks(i)
BeginningOfDemoName = Original.Substring(Original.LastIndexOf("(") + 2)
TickWithParenthesis = BeginningOfDemoName.Substring(BeginningOfDemoName.IndexOf(Chr(34)) + 4)
Tick = TickWithParenthesis.Split(" ")(1).Split(")")(0)
DemoName = BeginningOfDemoName.Split(Chr(34))(0)
ToList = DemoName + " at " + Tick
lstFavorites.Items.Add(ToList)
i += 1
End If
End If
Loop
Try to change this line
If bookmarks(i).Contains("Bookmark") Then
to
If bookmarks(i).IndexOf("Bookmark",
StringComparison.CurrentCultureIgnoreCase) >= 0 Then
Contains do a case sensitive comparison and your input string contains a lower case 'bookmark'