structured reference in excel vba: using '#Headers [col-name]' in Range - excel

folks,
not quite sure how to present this properly. so bear with with me:
i have an excel vba userform, and would like to do a calc inside the userform, retrieving data from a cell in an xls worksheet
the cell i can select is in col 'A' (GrossSales) and any row in the Revenue table; the selected cell then identifies 'active cell.row'. NOW, the column i want for specific data is defined elsewhere in a different column - the column could be found by #Headers[Sales]
since the worksheet is in development, i keep moving columns around; so i would like to use a 'dynamic' reference to the name of the column, rather than a 'static' name using column letter [like col 'H']
so, how it works, i click on a cell in col 'A' in a worksheet, and the userform gets me the active row: ActiveCell.Row; and currently, the xls has been 'static', so the column is simply identified as "H". in the userform then, i get my specific value to calc using Me.Sales.Value = Range("H" & ActiveCell.Row).Value
what i need to is to replace "H" with a header row 'name' so if i move columns this link still works.
i tried this:
Me.txtSales.Value = Range("Table_Revenue[[#Headers],[Sales]]" & ActiveCell.Row).Value
and i get this error:
..run time error 1004.. ..Method 'Range' of object '_Global' failed
so the reference to [#Headers],[Sales] is not returning the equivalent of the old "H"
can anyone tell me what i am missing here?
probably my lack of understanding of what is 'inside' the reference Table_Revenue[[#Headers],[Sales]]. it clearly isn't equal to H.
i tried putting the reference into a MsgBox to display, but that failed as well.
thanks,
ron

I'd suggest you use the ListObject instead:
Me.txtSales.Value = Intersect(Activecell.Entirerow, Activesheet.Listobjects("Table_Revenue").Listcolumns("Sales").Range).Value

rory,
u are correct. i was experimenting to understand range & value [i am still very wet behind the ears w/excel & vba]. i tried these things:
Me.txtSales.Value = Intersect(Activecell.Entirerow, Activesheet.Listobjects("Table_Revenue").Listcolumns("Sales").Range)
with dim txtSales Variant and then with dim txtSales Range
Me.txtSales = Intersect(Activecell.Entirerow, Activesheet.Listobjects("Table_Revenue").Listcolumns("Sales").Range).Value
with dim txtSales Variant
and #2 worked right, with the space between "Net Sales". so, as you said - it should work and it did.
what i think i found as well was that this version:
Range("Table_Revenue[[#Headers],[Sales]]" & ActiveCell.Row).Value
was commented as only working in excel, and not in vba.
one last thing: ListObjects worked because it was a 'table'? if it wasn't a table, but defined as a 'range', would it have worked?
anyway, i learned a lot - so thankyou very much for the solution, but thanks more for the learning experience.
ron

Related

How to use a variable WS name that references another WS and a variable range, with a MIN function

I have a WS named Stats and I want to fill a column with the MINIMUMs. The data is in the same WB, but on another WS called Data.
The data is in rows, so MIN calc would be performed on range B to IQ columns.
And I need to calc the MIN for rows 14 to 1868.
The following code works, but name and range of the data is hard coded:
Worksheets("Stats").Range("B14:B1868").Formula = "=MIN(Data!B58:IQ58)"
So my problem is that every workbook has a different worksheet name for the data. My macro has to work for all WBs.
I've tried the Indirect function, and this configuration only works for one row of data and populates the rest of the column with the same number(note that $A$2 is the location with the Worksheet name that contains the data):
Worksheets("Stats").Range("B14:B1868").Formula = "=MIN(Indirect($A$2&""!B58:IQ58"")"
I have tried so many different configs and can't figure this one out. I'll get a name or a ref error...it's driving me nuts, hoping someone here can help me!
Thanks in advance:-)
You can use a cell reference's value just as easily as a string literal.
(Sense of deja-vu there - I wrote that as part of an answer just this morning!)
So, instead of hard-coding "Data" into the formula
Worksheets("Stats").Range("B14:B1868").Formula = "=MIN(Data!B58:IQ58)"
you can insert the value from a cell
Worksheets("Stats").Range("B14:B1868").Formula = "=MIN('" & Worksheets("Stats").Range("A2").Value & "'!B58:IQ58)"
(I added apostrophes around the sheet name as well, just in case it contained spaces or other special characters.)

Populating cells with text using VBA

I want to select a value from one sheet and put it in a cell on a different sheet.
My script determines the proper value but I cannot get the value into the sheet.
This function returns the !Value error on the 6th line of the following excerpt:
Function PrintTest(Cell)
Dim iRow As Integer
Dim bs As Worksheet
Set bs = ThisWorkbook.Sheets("By System")
iRow = Cell.Row
bs.Cells(iRow, 6).Value = "Hello World"
End Function
I also tried using .Text.
Note: In the actual Script the text will be seeded from the other sheet and I have it stored in a variable. I am not looking for a way to get the same text into many different cells.
Update: Cell is passed from an Excel spreadsheet as an empty cell G4. Row is defined as 4. To call the functions I have been typing "=PrintTest(G4)" in my Excel worksheet named "By System" .
Update 2: Scott Holtzman answered the question in a comment. You cannot write to cells from a UDF called from within a cell. The fix was to call it from a button.
Set a cell value with Cells(Row, Col).Value="Some text"
If your sheet is active you do not need to fully qualify the address. If you activate the sheet you can just use Cells all of the time. If you have to retrieve data from a different sheet then you will have to qualify the address with the sheet name, i.e. Sheets("My Sheet").Cells(Row, Col).Value.
Also your code has Row=Cell.Row, but you are not saying what cell is active. In that case you are getting some arbitrary value. So that is where your error is, probably. Cell.Row=????? Also Row is an excel word. Use something like intRow for your variable. For example intRow=25. Cells(intRow, 6).Value="My Cell". If the cursor is on a cell you can say intRow=ActiveCell.Row.
When you have a problem such as this set a break point in your code (in your example, the Set statement). Thenm run your code. When it stops at the set statement you can hit F8 to step through one line at a time and examine your variables. Then you will see if Row is really a number or just garbage.
Hope that helps

Search through Excel tabs

I am not very familiar with VBA programming, though I have written a few basic modules. I am having some difficulty in coding the following problem. I would appreciate if someone could show a basic solution.
Problem: I have 3 tabs in an Excel file, "Rack1", "Rack2" and "Rack3". They each have a column called "tag". The tag column contains a code, made up of numerals 0 to 9999 and one letter, A or B.
I want to look up the first "A" code in Rack1, then find the matching "B" code. If the B code is not in tab "Rack1", I want to search tab "Rack2", then "Rack3" if it's not found in either.
After the "B" part is found, I want to have a Msgbox message - "Found in Rack..." OR "B part not found"
Then ... go on to the next A code. Thanks
Please let us know what have you tried so far to get things working at your end.
You may have to loop through with your requirement with all sheets with respective column and its range.
I am not very clear, what is your exact requirement but you can do something like this
declare variables of your sheets
Set sheet1 = Worksheets("Sheet1")
Set sheet2 = Worksheets("Sheet2")
Set sheet3 = Worksheets("Sheet3")
You have to set range as per your need. Now you have to loop your sheet1 and tag column. While searching you need check whether A is exist in respective cell by cell value see below example
If InStr(cell_value, "A") > 0 Then
Meanwhile you can check below post for your further reference.
Excel Looping through rows and copy cell values to another worksheet

How to extract column from cell (Excel, VBA)

I'm running into a (run-time error '1004': Application-defined or object-defined error) error while trying to write my first Excel VBA Macro. I've looked at similar questions on stack overflow and other sites, but my issue seems to be more basic than issues others are having.
Currently, I'm trying to take the data from two cells from one sheet and write them to another sheet. I understand that trying to find the column or row of a cell that I reference by cell or row is unnecessary, but eventually I will use for-loops and will substitute the specific cell references with variables.
Here are the two lines of code that I have:
Worksheets("Sheet2").Range("A1").Value = Worksheets("Sheet1").Range("A" & Worksheets("Sheet1").Range("B2").Row).Value
Worksheets("Sheet2").Range("B1").Value = Worksheets("Sheet1").Range(Worksheets("Sheet1").Range("B2").Column & "1").Value
The first line runs fine. It writes Sheet1's A2 to Sheet2's A1.
The second line does not run, does not write Sheet1's B1 to Sheet2's B1, references the error, and I'm not sure why.
Thank you for your time and help!
The .Columns property returns an integer, not a letter. Use the Range.Cells property if you want to define a range with a numerical row and numerical column.
Worksheets("Sheet2").Range("B1").Value = Worksheets("Sheet1").Cells(1, Range("B2").Column).Value
I suppose there is a larger purpose to this but as it sits, it is very verbose code.
your last lines from your question say that you want to fill Sheet2-A1 with Sheet1-A2 and Sheet2-B1 with Sheet1-B1
the most straightforward way is
Worksheets("Sheet2").Range("A1") = Worksheets("Sheet1").Range("A2")
Worksheets("Sheet2").Range("B1") = Worksheets("Sheet1").Range("B1")
I am a beginner at VBA just like you. You don't need to know everthing in VBA to make productive use of it. I made my first macro by RECORDING it, and it worked (but was hopelessly inefficient).
I had a problem similar to yours: looking up data on another worksheet. I created the following function:
Function GetMyNumber(C3ll)
MyCol = C3ll.Column
GetMyNumber = MyCol
End Function
To use it in a spreadsheet, just enter the formula into some cell, like D5,
=GetMyNumber(D5)
When you recalculate, the number 4 appears in cell D5. If you copy cell D5 into Cell F3, you will see in F3, =GetMyNumber(F3), and calculate will return a 6. Of course you can fill down or across, the argument is changed to the cell the formula is in. And if you want, you can offset with an argument referring to any cell.
Once you get this working, you can insert the code to do you matching and other tasks that make use of your column number MyCol to extract the number from the other worksheet. Remember, MyCol is an integer.
Hopes this helps.

Excel 2013, searching for partial text in one cell and overwriting adjacent cell if condition is met

I need to write a macro.
I've got a workbook with ~ 30000 rows (changes daily).
I need to search for expression "TRADE" within the strings in cells from column (A)
If string inside the cell contain expression TRADE I need to change string in relevant cell in column (B) (the same row) to expression "TRADEIN"
If condition is not met relevant cells from column (B) need to stay unchanged
What have I learned so far:
Formula =IF(ISNUMBER(FIND("TRADE", A1 )), 1, 2) changes adjacent cell value accordingly ONLY if placed directly inside cell and copied down in Excel.
Problems starts when I try to have string as an outcome
Formula: =IF(ISNUMBER(FIND("TRADE", A1 )), "TRADEIN", "") won't work ->error
Formula: =IF(ISNUMBER(FIND("TRADE", A1 )), ""TRADEIN"", "") won't work ->error
Then any attempts to make my macro insert more complex formulas into cells from VBA failed i.e.:
Below works fine:
For i=1 to i=NumberOfRows
ActiveSheet.Cells(i, 2).Formula = "= 2+2"
next i
Below won't work (again, formula works if placed in the cell directly):
For i=1 to i=NumberOfRows
ActiveSheet.Cells(i, 2).Formula = "=IF(ISNUMBER(FIND("TRADE", (i, 1)), 1, 2)"
next i
I think there's no point in listing all my failed attempts to make it work so far (loads of useless lines to read I presume) but by all means - correct me if I'm wrong.
I can't find solution as specific as my task and have got problems altering some found online whilst other won't work for me at all. Perhaps don't exactly know how to ask for what I need in the most effective way. Be very basic and try not to miss out any declarations from proposed modules/subs if you can - I'm not yet confident when it comes to using and creating objects and methods outside of a few examples I followed, or choosing/using the right type of variables with compatible methods/functions etc.
Using VBA this is how would accomplish the goal. This will find the last row used in column A to set the range to work through.
Sub test()
Dim w As Range
lrow = Range("A1", Range("A" & Rows.Count).End(xlUp)).SpecialCells(xlCellTypeVisible).Count
For Each w In Range("A1:A" & lrow).Cells
If w.Value = "trade" Then
w.Offset(0, 1).Value = "tradein"
End If
Next w
End Sub
Practice using the auto filter, once you have that worked out use the macro recorder to get a code to work on.
Select column A and the goto Data=>Filter=>text Filter=>Contains....type the word in the box to filter for.

Resources