Move to next row to browse it in the Integrated Web Browser - excel

Hy, I am using Microsoft Excel as an Integrated Google Map. It working fine for one row. Here is its code.
Private Sub CommandButton1_Click()
WebBrowser1.Navigate ActiveSheet.Range("D2").Value
End Sub
Basically what i want, I want when I click on the Next Map, the row 3 shold be populate in the map. It works fine for one record at a time and only for D2. But I want when I move "Next Map" button it should work for D3 and other as like for D2.
I am using below code but it does not work.
Sub SelectC()
Dim x As Variant
x = Cells(ActiveCell.Row, "D").Offset(1).Select
WebBrowser1.Navigate ActiveSheet.Range.Selection.Value
End Sub
It gives an error as under.
Please guide me where I am writing wrong code. thanks

I would do this slightly different. I would completely avoid the use of Activecell/Selection etc. You may want to see How to avoid using Select in Excel VBA
I will use 1 cell to store the current row number and use that. Here is an example. I am going to use say Cell D1 and make its font white so that it will not show. For demonstration purpose, I am not making it white. Change it to whatever you want. You have asked for NEXT button. I am also including a code which you can use for PREVIOUS.
See this example
Option Explicit
Dim ws As Worksheet
Dim lRow As Long
Dim NextRow As Long
Sub NextMap()
'~~> Set this to the relevant worksheet
Set ws = Sheet1
With ws
'~~> Get last row of the Col D
lRow = .Range("D" & .Rows.Count).End(xlUp).Row
'~~> Get the next row
NextRow = .Range("D1").Value2 + 1
'~~> Check if it is greater than last row
If NextRow > lRow Then
MsgBox "End of data reached"
Else
'WebBrowser1.Navigate .Range("D" & NextRow).Value2
'~~> Store the row number in D1
.Range("D1").Value = .Range("D1").Value + 1
End If
End With
End Sub
Sub PreviousMap()
Set ws = Sheet1
With ws
NextRow = .Range("D1").Value2 - 1
If NextRow < 2 Then
MsgBox "Begining of data reached"
Else
'WebBrowser1.Navigate .Range("D" & NextRow).Value2
.Range("D1").Value = .Range("D1").Value - 1
End If
End With
End Sub
In ACTION

Minimally, the code WebBrowser1.Navigate ActiveSheet.Range.Selection.Value should be changed to something along the lines of WebBrowser1.Navigate ActiveCell.Value. The syntax you originally used is poorly formed.

Related

How can I do a Calculation in Microsoft Excel VBA?

I'm 15 and I'm doing a Internship as a Developer and I've got a kinda hard exercise.
I have a Table with 3 columns, A is "Number" B is "percent" and C is "Value". The column "value" is blank and I Need to calculate the value with a macro button. I've tried this, but it was wrong because I didn´t calculate it in VBA:
Public Sub PushButton ()
Range("C2:C11").Formula = "=A2*B2/100"
Range("C2:C11").Value = Range("C1:C6).Value
End Sub
How do I solve this?
You are using a defined range, you could do it with a dynamic range like this:
Option Explicit
Sub PushButton()
Dim i As Long, LastRow As Long
With ThisWorkbook.ActiveSheet
LastRow = .Cells(.Rows.Count, 1).End(xlUp).Row 'first you need to find the last row on the active sheet
For i = 2 To LastRow 'then iterate through all the rows starting from 2, if row 1 has headers
.Cells(i, 3) = .Cells(i, 1) * .Cells(i, 2) / 100
Next i
End With
End Sub
If you need help understanding this code, let me know.
Edit: Explanation
Well, the first thing you must do is Dimension all your variables, and to help that you can use the Option Explicitright above all your code.
I've dimensioned 1 variable for the loop and another one to find the last row with text.
To find the last row what you are actually doing is going to excel, select the last row (1048576) and the column where it will have text, in this case 1 or column "A" and then pushing ctrl+Up excel and vba will get you to the last cell with text.
To do that you use Cells(Row, column) instead of manually inserting row 1048576 you can just use rows.count and it will be the same.
Once you get the last row you just iterate with a For iloop meaning For a variable called i which equals 2 (For i = 2) To LastRow (to the last row you calculated) VBA will repeat the code in between the ForAnd Next adding 1 number to i everytime the loop restarts.
In this case is just adding a number to the rows on Cells(i, 3) so you can modify that cell depending of its i value.
I think you need to question why Excel needs to calculate on demand rather than automatically like normal. Failing that there are a few options
You could change your calculation method to Manual using the following in the ThisWorkbook object
Option Explicit
Dim xlCalcMethod As XlCalculation
Private Sub Workbook_Open()
With Application
' Store users current method for when closing the workbook
xlCalcMethod = .Calculation
.Calculation = xlCalculationManual
End With
End Sub
Private Sub Workbook_BeforeClose(Cancel As Boolean)
' Reset calculation
Application.Calculation = xlCalcMethod
End Sub
and then when the button is pressed use the following code to calculate placed in a Module
Option Explicit
Public Sub Button_Click()
Application.Calculate
End Sub
Another option to do this without looping would be:
Sub CalculateRange()
Dim rng As Range
' Update for your Range
With ActiveSheet
Set rng = .Range("C2:C" & .Cells(.Rows.Count, "A").End(xlUp).Row)
End With
rng.Value2 = Evaluate(rng.Offset(0, -2).Address & "*" & rng.Offset(0, -1).Address & "/100")
End Sub
Finally, the way you've come up with is perfectly acceptable as VBA

Copy Check Box to Every 5th Cell with Command Button

I have an issue which i can't solve.I wrote this code:
Private Sub CommandButton2_Click()
Sheets("sheet2").OLEObjects("CheckBox1").Copy
Sheets("sheet3").Range("V7").PasteSpecial
End Sub
This code copy a checkbox from (sheet 2) to (sheet 3) starting from V7 cell. Now I want the next time I press the command button to paste the data to cell V12,next time to V17 etc. My vba knowledge is not very good as you can see.
This code will see how many checkboxes are already in the sheet you are pasting to and add 5 rows for each check box, then paste five rows under the last one.
Private Sub CommandButton2_Click()
' copy checkbox
Sheets("sheet2").OLEObjects("CheckBox1").Copy
Dim wks As Worksheet
Set wks = Sheets("Sheet3")
Dim cb As OLEObject, i As Integer
'determine how many boxes are already there and get count of cell to paste to
i = 7
For Each cb In wks.OLEObjects
If InStr(1, cb.Name, "CheckBox") Then i = i + 5
Next
'paste new checkbox
Sheets("sheet3").Range("V" & i).PasteSpecial
End Sub
Use a global variable. These must be at the top of your sheet, module, or form code above all subs and functions.
Then use that as the row number in your range. Range("V" & lRow)
Private lRow As Long
Private Sub CommandButton2_Click()
'Let's check if this is the first time the button has been used.
If lRow = 0 then
lRow = 7
Else
'Increment the row from the one we wrote to last time.
lRow = lRow + 5
End If
'Do the copy
Sheets("sheet2").OLEObjects("CheckBox1").Copy
Sheets("sheet3").Range("V" & lRow).PasteSpecial
End Sub
I dont know what data you got between in Sheet(3).Range("V7") and Sheet(3).Range("V12")
but juste before you're PasteSpecial, you shoud keep track where was the last time you paste data in Sheets("sheets3") in a specific cell in Sheet("sheets3"), in exemple : Sheets("Sheet3").Range("A1")
Then you'll be able to pastespecial to this cell 5 row under like this :
Sheets("sheet3").Range(Sheets("Sheets3").Range("A1").Offset(5,0)).PasteSpecial
right after that you update the Sheets("Sheets3").Range("A1") = Sheets("sheet3").Range(Sheets("Sheets3").Range("A1").Offset(5,0)).Address
So this should do the work :
Private Sub CommandButton2_Click()
Dim oWsSource as Worksheet
Dim oWsDestination as Worksheet
Set oWsDestination = ThisWorkbook.Worksheet("Sheets3")
Set oWsSource = ThisWorkbook.Worksheet("Sheets2")
'Do the copy
oWsSource.OLEObjects("CheckBox1").Copy
oWsDestination.Range(oWsDestination.Range("A1").Value).Offset(5,0)).PasteSpecial
oWsDestination.Range("A1").Value = oWsDestination.Range(oWsDestination.Range("A1").Value).Offset(5, 0)).Address
End Sub
All the answers put the first checkbox but the next one put it again to the same cell as before.I don't know if its matter but I use excel 2010.

Look for first cell with certain value in column, then insert 3 rows above

I work on a spreadsheet every morning and need to automate the following in a VBA macro:
In column AE, look for first value greater than zero, then insert 3 rows above the row containing that specific cell.
Something like this should work for you:
Sub tgr()
Dim ws As Worksheet
Dim lRow As Long
Set ws = ActiveSheet 'Adjust to be the correct worksheet if necessary
With Intersect(ws.UsedRange, ws.Columns("AE"))
On Error Resume Next
lRow = Evaluate("=MATCH(1,INDEX((ISNUMBER(" & .Address(External:=True) & "))*(" & .Address(External:=True) & ">0),),0)")
On Error GoTo 0
End With
If lRow > 0 Then
ws.Rows(lRow).Resize(3).Insert
Else
MsgBox "No values in column AE found to be greater than 0."
End If
End Sub

How to concatenate text from a column into a new column? VBA Excel

I'm new to vba programming and I would like to work on a function to fix salutations in an excel file.
To start, I would just like to append a Dear " to a name in the first column, and put this value in the next column, so that I would end up with the name in the first column and "Dear name" in the next column.
The function I have so far, is putting "Dear " in the next column, but it is not appending that to the text in the first column. Could someone help me correct my code?
Sub letterSalutationFixer()
Dim letterSalutationColumn As Range
Set letterSalutationColumn = Columns(1)
For Each Cell In letterSalutationColumn
Cell.Offset(, 1).Value = "Dear " & Cell.Text
Next
End Sub
PS. I do realise that I don't necessarily need to do this programmatically since it doesn't take that long to do with the functions already available, but I eventually want to expand this to fix other data with more complexity - and just thought I could start with something simple.
Many thanks in advance!
The reason it's blank is that Cell is equivalent to the whole column. You're close though. If you did...
For Each Cell In letterSalutationColumn.Cells
..l it would cycle through each cell.
However, the way it's written, it would cycle through each cell in the whole column, which could crash Excel, or at least slow things way down.
Here's a reworked version of what you're trying to do. It only acts on the cells in column A with content:
Sub Salutation()
Dim ws As Excel.Worksheet
Dim LastRow As Long
Dim NameRange As Excel.Range
Dim cell As Excel.Range
Set ws = ActiveSheet
With ws
LastRow = .Range("A" & .Rows.Count).End(xlUp).Row
Set NameRange = .Range("A2:A" & LastRow)
For Each cell In NameRange
cell.Offset(, 1) = "Dear " & cell.Text
Next cell
End With
End Sub
It also declares all variables, something you want to get in the habit of doing. Do a search on Option Explicit to learn how to force yourself to.
It also uses a With statement to fully qualify Object references, so that instead of just referring to Column(1) or Range(something) you're specifying that it's in ws, which has been set to the ActiveSheet.
Another way is the VBA alternative of
Using a formula in column B that runs the concatenation against the used part of column A (ie in B1 ="Dear " &A1 etc)
The formula then is copied over itself as a value to remove the formula
code
Sub QuickCon()
Dim rng1 As Range
Set rng1 = Range([a1], Cells(Rows.Count, "A").End(xlUp))
With rng1.Offset(0, 1)
.FormulaR1C1 = "=""Dear "" &RC[-1]"
.Value = .Value
End With
End Sub

Matching two data lists in Excel VBA and exporting to New Sheet

I receive an excel file monthly and have to export parts of it to a new file. I have a list of identifier numbers and I am trying to match the list of numbers in the selected list to the full file and then export the rows of relevant data to a new sheet.
Sub Run_All_Macros()
Application.ScreenUpdating = False
Sheets.Add.Name = "Output"
Call Convert_to_Numbers
Call Highlight_Selected_Contractors
End Sub
'Original Spreadsheet is formatted incorrectly
'Convert PSD Codes to Numbers
Sub Convert_to_Numbers()
Dim xCell As Range
Range("A2:A2500").Select
For Each xCell In Selection
xCell.Value = CDec(xCell.Value)
Next xCell
End Sub
'Highlight Selected Contractors
Sub Highlight_Selected_Contractors()
Dim Full, Selection, Code, SelectedCode As Range
Worksheets("Sheet1").Select
'Set all cells in Column A Sheet 1 to Full
Set Full = Worksheets("Sheet1").Range("A1", Range("A1").End(xlDown))
'Set all cells in Column A Sheet 2 to Selection
Worksheets("Sheet2").Select
Set Selection = Worksheets("Sheet2").Range("A1", Range("A1").End(xlDown))
'If the numbers match highlight the cell
For Each Code In Full
For Each SelectedCode In Selection
If Code.Value = SelectedCode.Value Then
*** Code.Select
Selection.Copy
Sheets.Select ("Output")
ActiveSheet.Paste
End If
Next SelectedCode
Next Code
End Sub
After executing this code column A in 'Output' is filled with zeros from A2:A2500. From messing around with breakpoints I've identified the problem to be where I've placed * but I'm not sure what's wrong with what's written there.
Thanks
There few errors in the code above and I also have few suggestions and finally the code.
ERRORS
1) Sheets.Add.Name = "Output" This line will give you an error if there is already a sheet called "Ouput". Delete the sheet first and then create it. You must be wondering that in case the sheet is not there, then how can I delete it? For such scenarios you can use On Error Resume Next which should be avoided in most cases.
2) When working with ranges, always specify which sheet you are referring to else Excel will always assume that you are referring to the "ActiveSheet". As you realized that Sub Convert_to_Numbers() was taking Output Sheet into consideration whereas you want the operation to happen in "Output" Sheet.
3) Dim Full, Selection, Code, SelectedCode As Range As mentioned in my comments earlier avoid using Excel Reserved words as variables. Also unlike VB.Net, if you declare variables as you did in VBA then only the last variable will be declared as Range. The other 3 will be declared as variant. VB defaults the variable to being type Variant. A Variant type variable can hold any kind of data from strings, to integers, to long integers, to dates, to currency etc. By default “Variants” are the “slowest” type of variables. Variants should also be avoided as they are responsible for causing possible “Type Mismatch Errors”. It’s not that we should never use Variants. They should only be used if you are unsure what they might hold on code execution.
4) Avoid the use of words like .ActiveCell, Selection, Select, Activate etc. They are a major cause of errors. Also they slow your code down.
SUGGESTIONS
1) Instead to using Sheets("WhatEver") every time, store it in a variable and then use that variable. Will cut down your code.
2) Indent your code :) it's much easier to read
3) Group tasks together. For example if you have to do with something with a particular sheet then keep it together. It is easier to read and amend if required.
4) Instead of hard coding your values, get actual ranges. Range("A2:A2500") is a classic example. Will you always have data till 2500? What if it is less or more?
5) End(xlDown) will never give you the last row if there is a blank cell in between. To get the last row in a column, say A in "Sheet1", use this
Sheets("Sheet1").Range("A" & Rows.Count).End(xlUp).Row`
6) Instead of looping, you can use the WorksheetFunction CountIf(). Loops should be avoided as much as possible as they slow down your code.
7) Use appropriate Error handling.
8) Comment your code. It's much easier to know what a particular code or section is doing.
CODE
Option Explicit
Sub Run_All_Macros()
Dim ws1I As Worksheet, ws2I As Worksheet, wsO As Worksheet
Dim ws1LRow As Long, ws2LRow As Long, wsOLr As Long
Dim xCell As Range, rFull As Range, rSelection As Range
Dim rCode As Range, rSelectedCode As Range
On Error GoTo Whoa '<~~ Error Handling
Application.ScreenUpdating = False
'~~> Creating the Output Sheet
Application.DisplayAlerts = False
On Error Resume Next
Sheets("Output").Delete
On Error GoTo 0
Sheets.Add.Name = "Output"
Application.DisplayAlerts = True
'~~> Working with 1st Input Sheet
Set ws1I = Sheets("Sheet1")
With ws1I
'~~> Get Last Row of Col A
ws1LRow = .Range("A" & Rows.Count).End(xlUp).Row
'~~> Set the range we want to work with
Set rFull = .Range("A1:A" & ws1LRow)
'~~> The following is not required unless you want to just format the sheet
'~~> This will have no impact on the comparision. If you want you can
'~~> uncomment it
'For Each xCell In .Range("A2:A" & ws1LRow)
'xCell.Value = CDec(xCell.Value)
'Next xCell
End With
'~~> Working with 2nd Input Sheet
Set ws2I = Sheets("Sheet2") '<~~ Input Sheet 2
ws2LRow = ws2I.Range("A" & Rows.Count).End(xlUp).Row
Set rSelection = ws2I.Range("A1:A" & ws2LRow)
'~~> Working with Output Sheet
Set wsO = Sheets("Output")
wsO.Range("A1") = "Common values"
wsOLr = wsO.Range("A" & Rows.Count).End(xlUp).Row + 1
'~~> Comparison : If the numbers match copy them to Output Sheet
For Each rCode In rFull
If Application.WorksheetFunction.CountIf(rSelection, rCode.Value) > 0 Then
rCode.Copy wsO.Range("A" & wsOLr)
wsOLr = wsOLr + 1
End If
Next rCode
MsgBox "Done"
LetsContinue:
Application.ScreenUpdating = True
Application.DisplayAlerts = True
Exit Sub
Whoa:
MsgBox Err.Description
Resume LetsContinue
End Sub
Let me know if you still get any errors :)
HTH

Resources