I am creating macro and I am stuck in creating the main page of VBA code. we have a sheet named "Renewal" in which all the customer information we dump. Column C we have customer number, Column D We have product type Dental, LIFE & Dis. Column A we have to put complete data, and Column B we have to put annual premium. Now I want the main page where I can one input box1 in which I put customer number, combo box1 in which 3 option I will get "DENTAL, LIFE, DIS., input box2 Date of completion, and input box3 annual premium. If input box1 and combo box1 condition satisfy then date will put on same row of column A and annual premium in column B respectively.
The wording of your question was very interesting, maybe a screenshot might be better. Ok this is what I have crafted. I am sorry I am not sure this code will work 100% as I have not got Word installed on this machine so had to write it in notepad, so may not be the best solution. As suggested in one of the comments - you have to add add() in the button1_click event. Hopefully this has been of some use.
Private Sub add() 'Add the add sub routine to the button1_click
Sheets("Renewal").Activate() 'makes the sheet activate
if textbox1.text <> "" and textbox2.text <> "" and textbox3.text <> "" and combobox1.text <> "" then 'condition
dim pos as integer 'used to find next position
pos = findNext() 'adds next position value
activesheet.cells(1,pos).value = textbox2.text 'adds Date of completion
activesheet.cells(2,pos).value = textbox3.text 'adds annual premium
activesheet.cells(3,pos).value = textbox1.text 'adds customer number
activesheet.cells(4,pos).value = combobox1.text 'adds product type
'unsure if combobox1.text is correct.
end if 'end of the condition
End sub 'end of sub routine
Private function findNext() 'this function finds the next position in sheet
dim x as integer 'used as a counter
x = 1 'counter = 1
do 'start of iteration
x = x + 1 'counting
loop until activesheet.cells(1,x).value = "" 'end when cell (A, counter) has no value
return x 'returns the counter value
End function 'end of function
P.S. If you are a complete begin beginner - This video may help you with the ui: https://www.youtube.com/watch?v=hCIpMwdKCgE
Related
I have a button that prints a form on the current record.
The form contains a combobox with something like: 123005TEST
This combobox is a lookup to another textbox which is a combination of three text boxes(on a different form):
=([OrderNr] & (""+[Aantal]) & "" & [SapArtNr])
OrderNr is 12300 and Aantal is 5 and SapArtNr is TEST, creating: 123005TEST
My question is, when I click print, is it possible to print a certain amount of copies based on Aantal 5, so printing 5 copies.
And here comes the tricky part.
To have each printed copy a different value in the combobox, so the first copy would have this written in the combobox on the printed paper: 123001TEST and copy two would be 123002TEST and so on, until 5.
I didn't understand which textbox will receive the sequential text. So I put a dummy in the example code:
Option Explicit
Private Sub cmdPrintIt_Click()
Dim strOrderNr As String
Dim strAantal As String
Dim strSapArtNr As String
Dim intHowManyCopies As Integer
Dim intCopy As Integer
Dim strToTextBox As String
strOrderNr = Me.OrderNr.Text
strAantal = Me.Aantal.Text
strSapArtNr = Me.SapArtNr.Text
On Error Resume Next
intHowManyCopies = CInt(strAantal)
On Error GoTo 0
If intHowManyCopies <> 0 Then
For intCopy = 1 To intHowManyCopies
strToTextBox = strOrderNr & CStr(intCopy) & strSapArtNr
Me.TheTextBoxToReceiveText.Text = strToTextBox
'put your code to print here
Next
Else
MsgBox "Nothing to print! Check it."
End If
End Sub
The main VBA procedure counts characters in table cells in a Word document. Since it can count characters different ways:
Count the "Objective" text for the selected table
Count the "Accomplishment" text for the selected table
Count both the Obj and Acc texts in each table (loop), for all tables (another loop)
I created calling procedures for each option above that calls the main procedure. This way I pass variables from the calling Sub to the main Sub. These variables (1) tell the main Sub whether I want to count what is in row 3 (objective) or in row 5 (accomplishment) or both, and (2) feed the If/then lines in the main Sub to make sure the right row is counted. At the time, it seemed elegant, in hindsight - not so much.
Word template below:
There will be text in O1 and the VBA will count it (characters, spaces + paragraphs) and output it in C1, and the C1 fill changes red or green if over/under the character limit. The same for A1 and C2 and so on for any number of following tables.
PROBLEM DESCRIPTION
The VBA was working for the actions above when I had the row/columns hard coded into various places in the code. If rows/columns were ever added/deleted from the tables, they would have to updated in multiple spots. It would be simpler if the row/column numbers were in one place and referred back to as variables, so I changed the row/col #s to public variables. Then the problem began.
In the code, I track (debug.print) what becomes of oRow (output row) & chcct (character count col) and both are 0 as the main Sub runs, despite both being initialized as 3 in the public Sub Row_Col_Num() below.
My public variables are at the top of the module before the first Sub() and denoted as Public. Sub Row_Col_Num() which contains the variable assignments is also Public. All Subs are in the same standard module.
Option Explicit
Public oRow As Integer 'row with "Objectives" text
Public aRow As Integer 'row with "Accomplishments" text
Public cOnA As Integer 'column that both obj and accmp text are in
Public cChCt As Integer 'column that the char count is output to
Public Sub Row_Col_Num()
oRow = 3
aRow = 5
cOnA = 1
cChCt = 3
Debug.Print "cchct pub sub: " & cChCt
End Sub
ATTEMPTS TO FIX PROBLEM & RESULTS
I used the variable normally and left it Public as well as the Sub that assigns the variables (oRow =3) values.
Sub TableCharCount_Obj()
'Run character count for the "Objectives" in the SELECTED table
Debug.Print "orow = " & oRow
Call TableCharCount(oRow, oRow) 'provide it 2x to make IF and FOR loop
End Sub
I tried putting the Sub() name in front of the variable when it is used, e.g. Row_Col_Num.orow, in the Sub above.
Call TableCharCount(Row_Col_Num.oRow, Row_Col_Num.oRow)
I tried the module name in front of the variable as well, e.g. Module1.orow.
Call TableCharCount(Module1.oRow, Module1.oRow)
RESULTS
#1 & #3 resulted in the macro counting the wrong row and outputting to the wrong cell.
#2 resulted in error "Expected Function or variable" at line: Call TableCharCount(Row_Col_Num.oRow, Row_Col_Num.oRow)
All 3 cases orow and cchct both continued to be 0 throughout the run.
QUESTIONS / SOLUTIONS
a) Can a Public variable (oRow) be used as an argument passed from calling Sub to called Sub as ByVal a As Integer?
b) Does Public Sub Row_Col_Num(), which assigns values to the public variables, have to be explicitly run or called to populate the variables in the other Subs w/ the correct values?
c) Should I call Public Sub Row_Col_Num() in every calling Sub before calling the main Sub?
Sub TableCharCount_Obj()
Call Public Sub Row_Col_Num() '<<< add this call
Call TableCharCount(oRow, oRow) 'provide it 2x to make IF and FOR loop
End Sub
This option seems like a bad design.
If it's not obvious, there was some mission creep as I added more capability For now, if I could get the public variables to work, it would be done. Appreciate any suggestion to get these variables to work. For the purposes of this question, I only left the code for the variable Sub, the first calling Sub and the main Sub. VBA below:
'#0 -- This creates variables for column and row number used in all the macros. Only need to change row/col number here if row/col are added/deleted
Option Explicit
Public oRow As Integer 'row with "Objectives" text
Public aRow As Integer 'row with "Accomplishments" text
Public cOnA As Integer 'column that both obj and accmp text are in
Public cChCt As Integer 'column that the char count is output to
'This assigns row/column numbers to the variables
Public Sub Row_Col_Num()
oRow = 3
aRow = 5
cOnA = 1
cChCt = 3
Debug.Print "cchct pub sub: " & cChCt End Sub
'#2
Sub TableCharCount_Obj() 'Run character count for the "Objectives" in the SELECTED table
Debug.Print "orow = " & oRow
Call TableCharCount(oRow, oRow) 'provide it 2x to make IF and FOR loop
End Sub
'other calling procedures removed
'#5
Option Explicit
Sub TableCharCount(ByVal a As Integer, ByVal b As Integer)
'Counts total characters in a cell w/in a table and outputs the number to a different cell, and colors the cell red or green if over/under the maximum number of characters.
Dim charCount, charWSCount, paraCount, charTot As Double
Dim iRng, oRng, txtRng As Word.Range
Dim i, max, s, t, x As Integer
Dim tcount, tbl As Integer
Dim DocT As Table 'for active doc tables
Debug.Print "cchct1= " & cChCt 'Debug.Print vbCr & "-----START-------" & vbCr Application.ScreenUpdating = False
If a <> b Then
tcount = ActiveDocument.Tables.Count
tbl = 1 'used in FOR loop, start w/ table #1
s = b - a '"STEP" used in FOR loop = # of rows between objectives text and accomplishments text Else
On Error GoTo ErrMsg 'handles expected user error of not selecting a table to execute on
tbl = ActiveDocument.Range(0, Selection.Tables(1).Range.End).Tables.Count 'ID the table that is selected
tcount = tbl 'prevents FOR loop from trying to run again
s = 1 '"STEP" used in FOR loop = # of rows between objectives text and accomplishments text / do not set to zero = infinite loop End If
'Debug.Print "# of Tables: " & tcount
For t = tbl To tcount 'loops thru the tables
Set DocT = ActiveDocument.Tables(t)
For x = a To b Step s 'loops thru the applicable row(s) in the table
'Debug.Print "x # start = " & x
'Debug.Print "table " & t
iRng = DocT.Cell(x, cOnA)
iRng.Select
'Count used in output
Selection.MoveLeft wdCharacter, 1, wdExtend 'computerstats requires the text itself selected, characters.count can use the whole cell selected
charWSCount = Selection.Range.ComputeStatistics(Statistic:=wdStatisticCharactersWithSpaces) 'counts bullets & space after bullet / not line breaks (paragraphs)
'Debug.Print "Comp statchar# " & charWSCount
'---------
paraCount = Selection.Range.ComputeStatistics(Statistic:=wdStatisticParagraphs)
'Debug.Print "#paras = " & paraCount
'----------
charTot = charWSCount + paraCount
'Output to table cell
i = x - 1 'output cell is 1 row above cell that is counted
Set oRng = DocT.Cell(i, cChCt).Range 'Char count ouput row,column
Debug.Print "cchct2= " & cChCt
oRng.Text = charTot
Set txtRng = DocT.Cell(i, cChCt - 1).Range '"# Char:" location row,column
txtRng.Text = "# Char:"
'Maximum # of char allowed in a cell. Used to change cell fill red or green.
max = 2000 '"Accomplishment" row (row 5) has a max of 2000
If i = 2 Then max = 1500 '"Objective" row (row 3) has a max of 1500
'Change color of cell to indicate over/under max # of characters
If charCount < max Then
oRng.Shading.BackgroundPatternColor = wdColorBrightGreen
Else: oRng.Shading.BackgroundPatternColor = wdColorRed
End If
'Debug.Print "x # end = " & x
'Debug.Print "--------Next x--------------"
Next x
'Debug.Print "------Next Table------"
Next t
ActiveDocument.Tables(tbl).Select 'attempt to move to top of 1st table if using CharCount_AllTab() or just to the top of the selected table for the other macros
Selection.GoTo What:=wdGoToBookmark, Name:="\Page" Selection.StartOf
Application.ScreenUpdating = True
Exit Sub
ErrMsg: Msgbox "Select a table by placing the cursor anywhere in the table. Press OK and try the macro again numnuts!", _
vbOKOnly, "Table not selected"
End Sub
I have a problem in my DataGridView, please refer to the image below.
Image 1 shows that I've clicked "Add to Cart" on one of my products, the DataGridView shows the product.
Image 1
The problem is when I want to add another product, the list of products in the DataGridView repeats itself instead of adding another different product.
Image 2 shows what happens when I clicked "Add to Cart" on a new product.
Image 2
Private Sub btn_add_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btn_add.Click
grd_cart.RowCount = grd_cart.RowCount + 1
For i As Integer = 0 To grd_cart.RowCount - 1
Dim product As String = grd_cart(0, i).Value
Dim price As String = grd_cart(1, i).Value
Dim quantity As String = grd_cart(2, i).Value
Dim subtotal As String = grd_cart(3, i).Value
grd_cart(0, i).Value = txt_product_id.Text
grd_cart(1, i).Value = txt_price.Text
grd_cart(2, i).Value = num_quantity.Value
grd_cart(3, i).Value = grd_cart(1, 0).Value * grd_cart(2, 0).Value
Next
End Sub
You don't need to cicle through the grid.
(Of course, this may depend on how you calculate the sub total.)
You just need to add a new Row to the grid, using the current values.
This can be a way to do it.
'Check whether the Price value is a number or not (to be safe)
'If can't be used as a number, return
Dim _Price As Long
If Long.TryParse(txt_price.Text, _Price) = False Then Return
'Calculate the subtotal value based on quantity and unit price
'I know not everyone calculates the sub total this way. In case, just add a comment.
Dim _subtotal As Long = CLng(num_quantity.Value) * _Price
'Add the new Row values
grd_cart.Rows.Add(New String() {txt_product_id.Text,
_Price.ToString,
num_quantity.Value.ToString,
_subtotal.ToString})
This is the result:
You might also present the values in Currency format:
'The output can also be formatted using the local Currency format
grd_cart.Rows.Add(New String() {txt_product_id.Text,
_Price.ToString("C"),
num_quantity.Value.ToString,
_subtotal.ToString("C")})
This is the result:
I've got an Excel file with N rows and M columns. Usually data are organized one per row, but it can happens that a data occupy more than a row. In this case how can I express that the second (or next) row has to refer to the first row?
In this example, AP.01 has got 5 rows of description, so how can I say that the other 4 rows refer also to the first code?
EDIT once that I did the association I have to export my Excel file into an Access DB. So I want to see the tables with the correct data.
If I have only one row for the description I wrote this code and it works:
If grid(r, 3).Text.Length > 255 Then
code.Description = grid(r, 3).Text.ToString.Substring(0, 252) + "..."
Else
code.Description = grid(r, 3).Text.ToString
End If
Instead if I have more than one row for the description I wrote this code and it doesn't work:
Do While grid(r, 1).ToString = ""
If grid(r, 1).ToString = "" And grid(r, 3).ToString IsNot Nothing Then
Dim s As String
s = grid(r, 3).ToString
code.Description = grid((r - 1), 3).ToString & s
End If
Loop
If it is a one-off, try the below. This will basically put a formula in every cell that refers to the cell immediately above it:
Select column A (from top until bottom of list (row N)
Press ctrl + g to open the GoTo dialogue
Press Special
Select Blanks from the radio buttons
The above will select all the blank cells in column A. Now enter = and press up arrow. Enter the formula by holding down ctrl while pressing enter. That will enter the same formula in every cell.
Try
Sub Demo()
Dim ws As Worksheet
Set ws = ThisWorkbook.Sheets("Sheet3") 'change Sheet3 to your data sheet
With .Range("A:A").SpecialCells(xlCellTypeBlanks)
.FormulaR1C1 = "=R[-1]C"
.Value = .Value
End With
End Sub
From your question I Guess that, you must be define a variable for last column Value. and check the value in respective column, if it is empty then use column value if not empty then take current value as last value.
'Dim LastValue as string
LastValue = sheet("SheetName").cells(i,"Column Name").value
for i = 2 to LastRow '>>>> here i am assume you run code in for loop from row to
'to last count row(LastRow as variable)
'Put your sheet name at "SheetName" and column index (like "A","B","C"...) at "Column Name"
if sheet("SheetName").cells(i,"Column Name").value <>"" then
LastValue = sheet("SheetName").cells(i,"Column Name").value
end if
'(Do your stuff using LastValue , you may generate lastvalue 1, lastvalue2 ..etc)
next'for loop end here
I am new at VBA.So kindly help me on this matter.
My UserForm has two ListBox controls in it, each with two columns. For example, ListBox1
Name Item
A 20
B 30
and listbox2:
Name Item
A 20
B 40
When I click a CommandButton, the procedure below attempts to compare both ListBox controls and returns whether or not the data in each column of data is correct. I believe the best approach would be to first compare Column 1 of ListBox1 with Column 1 of ListBox2. If those are identical, then compare the second columns of both ListBox controls. The procedure is supposed to return a MsgBox that says "Correct" if all columns are identical. Otherwise, the program should return a mismatch error. Here is the code I've tried so far.
Private Sub CommandButton1_Click()
Dim p As Integer, Tabl()
Redim Tabl(0)
For i = 0 To ListBox1.ListCount - 1
p = p + 1
Redim Preserve Tabl(p)
Tabl(p) = ListBox1.List(i)
Next i
For i = 0 To ListBox2.ListCount - 1
If IsNumeric(Application.Match(ListBox2.List(i), Tabl, 0)) Then
Msgbox"Correct"
End If
Next i
End Sub
Unfortunately, the program only calculates the first column repeatedly. How can I compare multiple columns?
Based on your description and a small evaluation of what your code does, you may be overthinking this. How about the following?
Private Sub CommandButton1_Click()
Dim myMsg As String
Dim byeMsg As String
myMsg = "Same name chosen."
byeMsg = "Those names don't match."
If ListBox1.Value = ListBox2.Value Then
MsgBox myMsg
Else
MsgBox byeMsg
End If
End Sub
Of course, instead of displaying a message using MsgBox, you could just as easily replace it with any code you need.