I am building a form to enter account information and order status. Each row needs to change based on the value of one of the cells on the same row, on this case cell "H". I can easily achieve this with conditional formatting but I think this makes the file bigger than programming code. I have tried some options but I can tell at this moment I'm way lost. I am attaching an example of what I want to accomplish. I don't know what to do at this point so if someone can help me I would really appreciate it.
A Worksheet_Change event macro¹ deals with, well, changes on the worksheet.
Option Explicit
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Target, Columns("H")) Is Nothing Then
On Error GoTo bm_Safe_Exit
Application.EnableEvents = False
Dim trgt As Range
For Each trgt In Intersect(Target, Columns("H"))
Select Case LCase(trgt.Value2)
Case "credit"
Cells(trgt.Row, "A").Resize(1, 12).Interior.ColorIndex = 45
Case "completed"
Cells(trgt.Row, "A").Resize(1, 12).Interior.ColorIndex = 10
Case Else
Cells(trgt.Row, "A").Resize(1, 12).Interior.Pattern = xlNone
End Select
Next trgt
End If
bm_Safe_Exit:
Application.EnableEvents = True
End Sub
¹ An event macro belongs on a Worksheet or Workbook code sheet; not a Module code sheet. For a worksheet code sheet, right click the worksheet's name tab and choose View Code. When the VBE opens, it will have the worksheet code sheet (typically titled something like Book1 - Sheet1 (Code)) in the foreground. Paste the code in and make any personalizing adjustments then tap Alt+Q to return to the worksheet.
Related
In the same workbook, I've got two worksheets: Model and Results.
My goal is to copy the value of a cell in Model (for e.g., F8) over to a cell in an array (c4 to I23) in Results called ResultsArray (see code below).
When I run my module, no error appears, but the code doesnt seem to work either (the value of F8 doesnt get copied over to the specified cell in ResultsArray).
Appreciate any help.
Tried running different variations of the code below
Sub CopyTest()
Dim ResultsArray As Variant
ResultsArray = Worksheets("Results").Range("C4:I23")
ResultsArray(1, 1) = Worksheets("Model").Range("F8").Value
End Sub
I'm using ResultsArray(1,1) because I am hoping to introduce a loop into the code to populate cells in the array based on the loop counter, e.g., ResultsArray(loopcounter,1)
So turns out I just needed to add "Set" in the 2nd line before "ResultsArray" when assigning the range from the worksheet "Model" to it:
Sub CopyTest()
Dim ResultsArray As Variant
Set ResultsArray = Worksheets("Results").Range("C4:I23")
ResultsArray(1, 1) = Worksheets("Model").Range("F8").Value
End Sub
I've tested this addition and it works
I want to copy cells of a certain colour in "Hacked" workbook to the "Official" workbook. I also want to loop across multiple sheets. Right now I am only testing on one sheet and the loop is already getting stuck.
Sub CopyBasel2()
Dim Hacked As Workbook
Set Hacked = Workbooks.Open("H:\BASEL Reporting - Oliver's Mock\Report Submission\BASEL2_0262CRT30062021G (Password Breaker).xls")
Dim Official As Workbook
Set Official = Workbooks.Open("H:\BASEL Reporting - Oliver's Mock\Report Submission\BASEL2_0262CRT30062021G.xls")
Dim Cell As Range
For Each Cell In Hacked.Sheets("SA-CR.1(CE)").UsedRange.Cells
If Cell.Interior.Color = 13434828 Then
Official.Sheets("SA-CR.1(CE)").Range(Cell.Address).Value = Cell.Value
End If
Next Cell
Debug.Print Hacked.Sheets("SA-CR.1(CE)").Range("C10").Interior.Color
End Sub
Thanks everyone for your guidance, I have managed to get my code to work as below, complete with a loop through an array of sheets.
The reason my earlier code couldn't work was because I was opening the "Official" file at the same time. When I closed it and ran my code, it ran smoothly. Anyone know the logic behind this?
Also, if anyone has a better/more elegant way of doing the array and the loops part, please feel free to share it.
Sub CopyBasel2()
Dim Hacked As Workbook
Set Hacked = Workbooks.Open("H:\BASEL Reporting - Oliver's Mock\Report Submission\BASEL2_0262CRT30062021G (Password Breaker).xls")
Dim Official As Workbook
Set Official = Workbooks.Open("H:\BASEL Reporting - Oliver's Mock\Report Submission\BASEL2_0262CRT30062021G.xls")
With Hacked
Set WSArray = .Sheets(Array("SA-CR.1(CE)", "SA-CR.2(CRM.1)", "SA-CR.3(CRM.2)", "SA-CR.4(RWA)", _
"SA-CR.6(OBS)", "SA-CR.6.1(CD)", "SA-CR.7(Recon)"))
End With
For Each ws In WSArray
For Each Cell In Hacked.Sheets(ws.Name).UsedRange
If Cell.Interior.Color = 13434828 Then
Official.Sheets(ws.Name).Range(Cell.Address).Value = Cell.Value
End If
Next Cell
Next ws
End Sub
I'm relatively new to VBA. I have a program I'm writing where the user is given the option to change their input from a 2 dimensional array in another user form.
The first user form, UserForm1, allows the user to input the information from text fields and saves it to the respective array row, i, when pressing a Save command button.
When the user presses an OK command button, the user is asked if they want to add another set of data. If they say no, they are asked if they want to change data. If they say yes, then another user form, UserForm2, is opened.
The code for UserForm1 is similar to the code below:
Public MyArray as Variant, i as Integer
Sub Userform_Initialize()
ReDim MyArray(100,4)
End Sub
Sub SaveButton_click()
MyArray(i, 1) = TextField1.Value
MyArray(i, 2) = TextField2.Value
MyArray(i, 3) = TextField3.Value
MyArray(i, 4) = TextField4.Value
End Sub
Sub OKButton_click()
If msgbox("Do you want to add more data?", vbYesNo) = vbNo Then
If msgbox("Do you have corrections to be made?",vbYesNo) = vbYes Then
Load UserForm2
UserForm2.Show
Else: Exit Sub
End If
Else: i = i + 1
Exit Sub
End If
End Sub
In UserForm2, the user chooses the row number, i, from a combo box. When the row number is selected, the array information is automatically populated in text fields from UserForm1.
When the user presses the Save command button, it should pass the information from the text fields and write it to the respective row.
The code for UserForm2 is similar to the code below:
Public j as integer
Sub Userform_Initialize()
For j = 1 to UserForm1.i
ComboBox1.AddItem (j)
Next
End Sub
Sub SaveButton_click()
UserForm1.MyArray(ComboBox1.Value, 1) = TextField1.Value
UserForm1.MyArray(ComboBox1.Value, 2) = TextField2.Value
UserForm1.MyArray(ComboBox1.Value, 3) = TextField3.Value
UserForm1.MyArray(ComboBox1.Value, 4) = TextField4.Value
End Sub
Stepping through the code, the values from MyArray should be properly referenced, and I can see the values initially saved from UserForm1. However, the values are not changing as I step to the next line.
Does anyone have a solution for my problem? Thank you in advance for your help!
I believe I found my solution. I had to declare the array in the module containing the code to start the program as a public variable. After I did that and modified the code, the values were written properly to the array.
If anyone has other solutions, though, I would like to know. I'm not that experienced with VBA, so I want to hear other solutions.
I have created a forum in vb6 and made connection with a database in access,everything went perfect.
my problem is in my form there is 2 combobox one to select Number and other to get me other numbers (watch the video to understand )
anyway the first combo is working and the second combo is working too but after selecting different number from the first combo i don't get anything in the second combo.anyway i know i just miss something in the code something very stupid
i have uploaded a video so you can see my problem, thanks in advance.
Private Sub Form_Load()
liaison
Do Until rspatient.EOF
Me.npa.AddItem rspatient.Fields(0)
rspatient.MoveNext
Loop
End Sub
Private Sub npa_Click()
rspatient.MoveFirst
Dim cr As String
cr = "npation ='" & npa & "'"
rspatient.Find cr
nom = rspatient.Fields(1)
prenom = rspatient.Fields(3)
rshospita.MoveFirst
nh.Clear
While rshospita.EOF = False
If UCase(rshospita.Fields(14)) = UCase(npa) Then
nh.AddItem rshospita.Fields(0)
End If
rshospita.MoveNext
Wend
End Sub
video for more detail :
https://www.youtube.com/watch?v=Tidm18_tvp0
The simplest possible reason for your problem is that you don't have any hospital records associated with your second patient. Check that first.
However, your code is also a bit convoluted. A simpler way to do what you want is to use Filter instead of Find. Filter restricts your recordset to only those records which match the filter, so you can simply iterate the filtered recordset the same way you do the whole one (rspatient). Something like this:
Private Sub npa_Click()
With rshospita
.Filter = ".Fields(14) = '" & npa & "'"
.MoveFirst
nh.Clear
Do Unitl .EOF
nh.AddItem .Fields(0)
.MoveNext
End With
End Sub
I simply want to fill-up cells in my spreadsheet from a VBA function. By example, I would like to type =FillHere() in a cell, and in result I will have a few cells filled-up with some data.
I tried with such a function:
Function FillHere()
Dim rngCaller As Range
Set rngCaller = Application.Caller
rngCaller.Cells(1, 1) = "HELLO"
rngCaller.Cells(1, 2) = "WORLD"
End Function
It breaks as soon as I try to modify the range. Then I tried this (even it's not really the behavior I'm looking for):
Function FillHere()
Dim rngCaller As Range
Cells(1, 1) = "HELLO"
Cells(1, 2) = "WORLD"
End Function
This is not working neither. But it works if I start this function from VBA using F5! It seems it's not possible to modify anything on the spreadsheet while calling a function... some libraries do that though...
I also tried (in fact it was my first idea) to return a array from the function. The problem is that I only get the first element in the array (there is a trick that implies to select a whole area with the formula at the top left corner + F2 + CTRL-SHIFT-ENTER, but that means the user needs to know by advance the size of the array).
I'm really stuck with this problem. I'm not the final end-user so I need something very easy to use, with, preferably, no argument at all.
PS: I'm sorry I asked this question already, but I wasn't registered at that time and it seems that I can't participate to the other thread anymore.
You will need to do this in two steps:
Change your module to be something like:
Dim lastCall As Variant
Dim lastOutput() As Variant
Function FillHere()
Dim outputArray() As Variant
ReDim outputArray(1 To 1, 1 To 2)
outputArray(1, 1) = "HELLO"
outputArray(1, 2) = "WORLD"
lastOutput = outputArray
Set lastCall = Application.Caller
FillHere = outputArray(1, 1)
End Function
Public Sub WriteBack()
If IsEmpty(lastCall) Then Exit Sub
If lastCall Is Nothing Then Exit Sub
For i = 1 To UBound(lastOutput, 1)
For j = 1 To UBound(lastOutput, 2)
If (i <> 1 Or j <> 1) Then
lastCall.Cells(i, j).Value = lastOutput(i, j)
End If
Next
Next
Set lastCall = Nothing
End Sub
Then in order to call the Sub go into the ThisWorkbook area in VBA and add something like:
Private Sub Workbook_SheetCalculate(ByVal Sh As Object)
Call WriteBack
End Sub
What this does is return the value of the topleft cell and then after calculation completes populates the rest. The way I wrote this it assumes only one FillHere function will be called at a time. If you want to have multiple ones which recalculate at the same time then you will need a more complicated set of global variables.
One word of warning is that this will not care what it overwrites when it populates the other cells.
Edit:
If you want to do this on a Application wide basis in an XLA. The code for the ThisWorkbook area should be something like:
Private WithEvents App As Application
Private Sub App_SheetCalculate(ByVal Sh As Object)
Call WriteBack
End Sub
Private Sub Workbook_Open()
Set App = Application
End Sub
This will wire up the Application Level calculation.
What you're trying to do won't work in Excel - this is by design.
You can do this, though:
Function FillHere()
Redim outputArray(1 To 1, 1 To 2)
outputArray(1, 1) = "HELLO"
outputArray(1, 2) = "WORLD"
FillHere = outputArray
End Function
If you then select two adjacent cells in your worksheet, enter =FillHere() and press Control+Shift+Enter (to apply as an array formula) then you should see your desired output.
Fundamentally, a function can only affect the cell it is called from. It sounds like you may need to look at using the Worksheet_Change or Worksheet_SelectionChange events to trigger the modification of cells in the intended range.
You can do this indirectly using a 2-stage process:
Write your UDF so that it stores data in a sufficiently persistent way (for example global arrrays).
then have an Addin that contains application events that fire after each calculation event, looks at any data stored by the UDFs and then rewrites the neccessary cells (with warning messages about overwrite if appropriate) and reset the stored data.
This way the user does not need to have any code in their workbook.
I think (but do not know for sure) that this is the technique used by Bloomberg etc.