How do I select specific cells in VBA? - vba

Basically I need to select specific cells on an excel sheet in vba. For example the code should be able to select a5, a10, a15. I do not want the cells in between them, just the ones I listed. Is there a specific function that will do this? It seems like .Range could only take start cell and ending cell.

You'd use this: Range("A5,A10,A15").Select
To add additional cells, just use more commas.
Alternately, you can utilize the Union method to join multiple range objects into a single Range object.
Note that it is generally not a good idea to select cells in VBA as nearly everything can be done without selection. This is a frequent mistake made by people new to VBA due to generated macros (Record Macro) recreating what you do rather than the result you want.

Related

Conditional formatting 1 cell based on cell input on another sheet, apply to entire row

For work I need to create a resource management excel file. My goal is to create an overview as is seen here:
If John would have taken a few hours off, or if he has a fey hours of sick leave, I would like to turn this cell only to change colour so I know that John will be absent for whatever reason on this day.
However, since I'm creating this for an entire row (for a whole year), I do not want to create conditional formatting per cell because that would be plain madness.
Here is an example per employee (in this example John):
enter image description here
So what I need is a formula to check if a cell in a row (for example sick leave) on the employee worksheet is grater than 0 and then change the colour of only the corresponding cell on the recourse planning worksheet, not the entire row.
Does any of you guys know if this is possible in excel 2016? Preferably without VBA scripting since I have to transfer this excel file to a co-worker who is not into VBA programming.
Thank in advance.
Nuntius transmittendus!
This is definitely possible without any code. Use CountIf() as tinus087 commented. The tricky part is how to create the address range used by the CountIf() so that you can put one conditional format on all the cells. On the the one hand you need the column of the cells being checked to match the column of your total cell. On the other hand the worksheet tab name needs to change depending on which row you are on. So use INDIRECT() to point to the correct worksheet and OFFSET() to look at the correct cells.
So, for cell C4, the formula you want to use as the range in your CountIf() is OFFSET(INDIRECT($A4&"!A1"),3,COLUMN(C1)-1,4). When applied to cell C4 this creates address John!C4:C7. When used for cell D4, it results in John!D4:D7.
You'll probably want some error checking to deal with the #REF! error happens when the formula is applied to a row without a first name or where the name listed doesn't match any worksheet tabs.
Something else to think about, if you haven't already, what happens if there are two John's? Is the 2nd John going to be named John2?

IfError, leave formula in place/don't do anything?

I have a spreadsheet, where I'd like to drag down a particular index/match formula, but where the formula does not return a value, I'd like it to keep the formula that is already in place (which sums up a few of the items below it).
I know that you could just use the cell reference for the if_error part of the formula, but this would return the value of the cell as it is now, and wouldn't use the current formula to generate a new value based on the values returned by the index match formula.
I have attached pictures below. Basically, I want to leave the sum formulas as is, but just be able to drag down that first index formula (the actual spreadsheet I'm dealing with has many different spaces, and is very long, otherwise I'd just copy the formula manually).
If this isn't possible, are there any other solutions? Another thing I tried was for each index/match that didn't return a value, I had it return the formula as a string, and then I'd copy/paste special with values, replace the column in the formula that is a string to the column I'm looking for, and then it would evaluate the formula that was, before, a string. But then you lose the formulas for all the other cells.
So the issue is that some cells are used to sum, and I don't want to drag the formula over those cells, but at the same time, I do need to use the formula over the whole range, otherwise it would just take too long.
Once you put a formula in G1, the previous formula in that cell is no longer available, so referencing G1 in your new formula would just produce a circular reference.
Instead think of a formula that combines both formulas into one: it should detect in which situation it is and then perform the appropriate calculation.
In your case, I think this formula will do what you want:
=IFERROR(INDEX($M$3:$M$9, MATCH(F1,$L$3:$L$9)), IF(E1="", "", SUM(G2:G4)))
Put it in cell G1 and copy it down.
Note how it looks at column E to decide whether it should do the sum. I also adapted a bit the part you already had, by making some references absolute (adding some $), because the area in the L and M columns is positioned at fixed rows.
Add a helper column in row H for your Index-Match formula and copy it all the way down. Then, in row I do an if statement. If row H meets the criteria you want, do that, else use row G.
So I think I found a good solution, especially in the case where you are going to be using the spreadsheet over and over, and the format won't change much. This might be too specific for anyone to use, but posting it just in case someone gets some use out of it.
First I created two macros, one to hide the sum rows, and another to unhide all the sum rows. I got the sum rows from another column by copying all the formulas across to the new column I'm looking at. Numbers will of course be wrong, but the sum formulas will be what we want to keep. You can speed this up by finding "sum" in formulas and then selecting all of the results.
Next, use the macro which hides all the sum rows.
Next, create the index formula in the first row. Control shift down to select all rows beneath. Then, "find", and "go to special" and select "only visible cells", and then hit F2, and control enter, and this will copy the formula down to all the visible cells, ie the non-sum cells.
Then use your unhide macro, and it should be golden!
You can use this technique for any spreadsheet where the source data format is different from target, and where you have fixed formulas in the target which you always will need.

Display change in value of a cell in adjacent cell using excel VBA

I have a excel sheet that display's price on certain items in a column by looking up amazon API using excel vba. The price of may change overtime. So I am trying to display the difference in prices each time i run my macro, in a cell adjacent to the cell that displays price.
But I am not sure how to achieve this. Can any body guide me on how to achieve this?
This is just a sample, it must be adapted to your schema and data layout. Say the prices are stored in column A from A1 to A100. Say you already have a macro called RefreshData() that updates column A. In B1 enter:
=C1-A1
and copy down. This macro store the current values in column C before refreshing the data:
Sub DoUpdate()
Range("A1:A100").Copy Range("C1")
Call RefreshData
End Sub
Column B will display the price difference.
Something like this?
Let's say your data are in a range A2:A10
Dim rng as Range
Set rng = Range("A2:A10")
rng.Offset(0,1).Value = rng.Value
Run this before you run your original macro to store the values in an adjacent column before the values change. You may need to make the range dynamic, depending on your needs.
Without seeing you code, I cannot give a detailed answer. However, I ran across a similar problem once, not using Amazon API though, but a sharepoint connection.
If the amazon api is somewhat similar to the sharepoint stuff, I guess it refreshes cells when you click "update", or run the update sub. In that case you will have to either create an array to store the old prices in vba (very slow process), and then write them to your table, or create a separate tab where you store the item-lastPrice combination.
I ended up storing not only current price but all prices and the date/time of the price, to be able to see change over time.
For the copying of data itself using VBA, either of the above methods should work. In my initial code I used vba loops :-p, but copying using excel functionality is much faster.

Trying to use excel formula or VBA

I have two different workbooks. Book 1 and Book 2 both have the same number of columns A through M.
I want to do match the records between two workbook, for example: I have a column A name Birthday, Column B City, Column C Passport Number......., in worksheet 1 & 2. I want to match worksheet 1 Cell A1 from the Range A:A worksheet 2, If the record in column A cell 13 not matching it shows Birthdate not match in N13 Workbook 2, If it does not match with worksheet 1 Cell 13 from the Range B:B worksheet 2 it shows city not MATCH in Column N 13 in workbook 2, and so on till column M.
I am using the formula below but it's not working properly, I don't know what I am missing and what formula should I add in. I have no idea about VBA. But I want to see is it easier to do by using excel formula or vba?
IF(COUNTIF(Target!$A$2:$A$5964,Source!A8)=0,"Birthday",IF(COUNTIF(Target!$B$2:$B$5964,Source!B8)=0,"City",IF(COUNTIF(Target!$C$2:$C$5964,Source!C8)=0,"Country",IF(COUNTIF(Target!$E$2:$E$5964,Source!D8)=0,"Passport Number Mismatch in Target",IF(COUNTIF(Target!$F$2:$F$5964,Source!E8)=0," Travel Date Mismatch in Target",IF(COUNTIF(Target!$G$2:$G$5964,Source!F8)=0,"First Name Mistmatch in Target",IF(COUNTIF(Target!$H$2:$H$5964,Source!G8)=0,"Full Name Mismatch in Target","Match in Target")))))))
Thanks in Advance.
VBA has access to these same worksheet formula functions (e.g. COUNTIF): there really aren't column or matrix functions that VBA has that formulas don't have.
However, VBA lets you write loops (e.g. while, for), it allows if-statements, procedure calls, and many lines of code so your calculations can have more steps and hence be more complex. VBA also lets you have temporary space in the form of arrays (and strings and objects, too) (so you don't necessarily need to use columns for temporary space as one might do with formulas). VBA also allows recursion, which makes some calculations easier (to some definition).
VBA provides an imperative programming model. VBA procedures can read and write any cell of the spreadsheet. Imperative programming, on the other hand, needs to be triggered somehow such as by using a button.
By contrast, the data-flow programming model with formulas will automatically recalculate whenever their input sources change, which is good. But there are some cases it doesn't handle naturally (e.g. recursion).
Another option is to combine VBA with formulas, by writing new formulas that are then implemented in VBA. If you are doing that, the VBA can only return information thru function return values; it cannot otherwise modify the spreadsheet.
So, if you can think of how to do this easier using loops (and arrays) or recursion and maybe with a button to trigger the computation (or by using custom formulas) then VBA might be interesting.

Output all cells in a named range in Excel?

I have a named range in Excel (called JourneyReference) that contains data to do with common journeys employees make (travel time, distance, etc). I would like to output all of the cells from this named range on several sheets.
The reason I am looking at doing it this way is because the named range will be updated regularly, and thus I'd like the changes in it to propagate through to all the sheets.
Is this possible in Excel 2007? Or, if there is perhaps a better way of doing this, please let me know. Thanks.