Repeat command and increase range - vba

I have almost no experience with VBA that being said.
I have a function in "B21" that I have copied over the same row up to "Z21"
I want the results from these cells to be shown on a different sheet all in one Column starting at "B2" and repeating until till it reaches the end.
This is what I have for that.
Sheets("Barlist").Range("B2").Value = "B21"
Alternatively the function I have in "B21" that I have copied over to repeat itself is:
=IF((COLUMN()-1)<$B$16,ROUND(TAN(RADIANS($B$5))*(($B$6)-($B$15*(COLUMN()-2))),2)+($B$11-0.33),IF((COLUMN()-1)=$B$16,$B$18,""))
So if I could just tell in to repeat this function down Column "B" until it returns a blank result that would should work to.

This code would cycle through all cells from B21 to the last column in row 21 with data and if the cell is blank you would need to add the code for what you wanted to do with that cell. Otherwise, the cells gets placed into "Barlist" starting at B2 and working down (using the next blank row each time)
Sub NAMEOFSUB()
Dim LastCol As Long
Dim CurCol As Long
Dim DestRow As Long
LastCol = Sheets("CURRENT SHEET NAME").Cells(21, Columns.Count).End(xlToLeft).Column
For CurCol = 2 to LastCol
If Sheets("CURRENT SHEET NAME").Cells(21, CurCol).Value = "" Then
'Do Something with your blank cell such as add a .Formula
Else
DestRow = Sheets("Barlist").Range("B" & Rows.Count).End(xlUp).Row + 1
Sheets("Barlist").Range("B" & DestRow).Value = Sheets("CURRENT SHEET NAME").Cells(2, CurCol).Value
End If
Next CurCol
End Sub

What exactly are you trying to do?
Right now your code would just enter the value "B21" in cell B2 on sheet Barlist.
If you want to add a reference to that cell, you could use Sheets("Barlist").Range("B2").FormulaR1C1="R21C2"
Although I really don't see any reason to use VBA at all for this. If you want a dynamic range, so it is linked to the original range, you could simply use the Transpose Function.
For your example, select the cells B2 to B26 on your Barlist sheet. Press F2 (should enter cell B2) and enter the formula =TRANSPOSE(SHEET!B21:Z21). This is an array function, so you don't just press enter, you have to press CTRL+SHIFT+ENTER at the same time to enter it. Excel will automatically append little curly brackets {} around the formula so you know it's an array formula.
If you want static values, select the range B21:Z21 you want to copy, then go to cell B2 on your Barlist sheet and right click>paste special and use the "trasnpsose" option

Related

Weird activecell.offset output

Sub Link()
Dim Turbidity As Long
Dim RawTurbidity As Range
'Sets variables Turbidity being the ActiveCell and RawTurbidity referring to the last captured cell in raw sheets'
Turbidity = ActiveCell.Row
Set RawTurbidity = Sheets("Raw Data").Range("C4").End(xlDown)
'The formula assigning the last captured cell in Raw sheets to the active cell '
Sheet1.Range(Sheet1.Cells(Turbidity, 4), Sheet1.Cells(Turbidity, 4)).Formula = RawTurbidity
End Sub
So this is the code I have and currently it does what it's suppose to do. We have two sheets atm sheet1 and Raw Data An instrument spits out data into column C of Raw data starting wtih C4 and going all the way down. The current code I wrote in essence paste the newest value the instrument spits out to the active cell in sheet1. I have a code on Raw Data that runs the macro only when a change is made to column C4 and lower. And it works exactly how I want it to however...
my question or issue is that when I add activecell.offset(1,0).select in order to have the activecell automatically go to the next row in sheet1 without me moving the mouse the macro copies and paste the same data into the next 4 cells. If I have the intrument spit out the data again than this time it occupies the next 6 rows with the same data.
Joe B, I think you are making this harder than it is.
Last value in a sheet column gets copied to the next open row in a specified column on another sheet? Is that right?
Option Explicit
Sub Link()
Dim ws1 As Worksheet
Dim wsRaw As Worksheet
Dim ws1LastRow As Long ' "Turbidity"
Dim wsRawLastRow As Long ' "RawTurbidity"
' I suggest you just name the sheets using the developer prop window
'It cuts this whole part out as you can call them directly
Set ws1 = ThisWorkbook.Worksheets("Sheet1")
Set wsRaw = ThisWorkbook.Worksheets("Raw Data")
ws1LastRow = ws1.Cells(ws1.Rows.Count, "A").End(xlUp).Row 'lets say you are pasting to column A
'ws1LastRow = ws1LastRow + 1
'There you go the next writable cell row, this is wasted code though, see below you just increment when you need it
wsRawLastRow = wsRaw.Cells(wsRaw.Rows.Count, "C").End(xlUp).Row 'This method doesn't care if your data starts in C4
'No formula needed, it is a straight "copy" here, actually faster as its an assignment
ws1.Cells(ws1LastRow + 1, "A").Value = wsRaw.Cells(wsRawLastRow, "C").Value
'the next open cell (defined by row) in your sheet 1 column is equal to the last row of your Raw Data sheet column
End Sub
Issue is that the data in sheet one is not inputted in order. A person may need the data calculated to row 10 and the next calculation needs to be in row 20 hence the need to copy the data into the active cell.
This was my bad for not stating that in the initial post as it's the primary reason for this strange formula.

Saving number as text, how to automate it

I have a 7702216772 number inside a cell. If I put a ' before the fist digit and click Enter Excel transforms the number to a text and puts a green triangle at the left top of the cell:
I have many rows of similar numbers all of which need to be transformed into text. However clicking each and adding ' before the first symbol and clicking Enter would take a lot of time. Is there any way to do it programatically?
I tried using formula: ="'"&H4 but it doesn't do what's expected - the green triangle never appears on the result cell.
I also tried setting cell format to Text, but the green triangle doesn't appear in that case too.
I need the green triangle to appear at the upper left corner, just like at the picture!
If all your number are in a single column, the following code will do it:
Sub foo()
Dim ws As Worksheet: Set ws = Sheets("Sheet1")
'declare and set your worksheet, amend as required
LastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row
'get the last row with data on Column A
For i = 1 To LastRow 'loop from row 1 to last
ws.Cells(i, "A").Value = "'" & ws.Cells(i, "A").Value 'add the ' before the number
Next i
End Sub
Change the "A" to whichever column you are using.
Just Select the cells you wish to process and run this short macro:
Sub Textify()
Dim rng As Range, r As Range
Set rng = Selection.Cells.SpecialCells(2, 1)
For Each r In rng
r.Value = "'" & r.Value
Next r
End Sub
Non VBA answer; I'm using Column G in this answer but it depends on where your numbers are. You'll have to change the cell but I think you will be ok with this.
In an empty cell, enter formula: ="'"&G4
Use the fill handle or Ctrl+D to fill it down to the length of Column G's values.
Select the whole of Column G's values and copy them to the clipboard
Select the same range in Column G, right-click, select Paste Special and choose Values
I have tested it now for several times and it worked always
Cells(xx, xx).FormulaR1C1 = "'" & Cells(xx, xx).Value
Same would work for ActiveCell or whatever you like.

How to combine the values of different cells into strings of our own format and store it in the third cell?

I have a table that has two columns namely Description and Amount. I want to write those details in a third cell in the form of Description1-Amount1, Description2-Amount2, and so on till there is an empty row. Please look at the image for better understanding.
So, now in the Sheet 2 in cell A1, I want the content as Dad-500, Chegg-123. Suppose if there are more items, I want them to be subsequently added.
I have designed a macro such that on click, whatever Values are present in the table at that point of time should be saved in Cell A1 of Sheet2.
My code is:
Sub database
Dim emptyRow As Long
Dim mix1 As String
mix1 = "=CONCATENATE(Sheet1!C5,""-"",Sheet1!D5)"
Sheet2.Activate
'Determine emptyRow
emptyRow = WorksheetFunction.CountA(Range("A:A")) + 1
Cells(emptyRow, 1).Value = mix1
End Sub
In the above code, Sheet1!C5,""-"",Sheet1!D5 represents Description (C column) and Amount (D column) respectively.
This code copies the formula into the second sheet. But I want those details to be converted as a string and then store in the empty cell (A1), such that next time if I run the macro with the different set of values in the table, those details should be copied in Cell A2 (since that is the next empty cell) and the values in cell A1 should not be changed since it is converted to string.
Now the problem I am facing is if I run the macro for the second time, both the values in cell A1 and A2 are changing since both these cells contains formulas and not strings.
Please help me as to how to combine the values of different cells into strings of our own format and store it in the third string.
Transfer the values without creating a formula.
sub database
with sheet2
.cells(.rows.count, "A").end(xlup).offset(1, 0) = _
sheet1.cells(5, "C").value2 & chr(45) & sheet1.cells(5, "D").value2
end with
end sub

Excel Range Reference

Let me preface this question by saying I am not super technical so much of my verbiage may seem obscure..
On sheet1 I have three seperate horizontal ranges of cells (3 seperate series of steps):
A1:D1
A2:C2
A3:E3
On sheet two, I'd like to link to create live links to these ranges, such that if I change information on sheet1, it will be automatically reflected in sheet2.
The catch is, that on sheet2, I want the ranges to be listed after one another in one row, to create one long series of steps.
Range1-->Range2-->Range3 (all on one row)
How do I ensure that if I add an additional step to, say, the first range on sheet1, that on sheet 2, the new cell will be added and the following cells will all be pushed over to the right by one cell?
To accommodate ranges that might grow, start from the first cell and then find the last occupied cell with End(xlToRight). Once you've found all the range extents, you can combine them with an array UDF:
Function ConcatRanges(ParamArray ranges()) As Variant()
Application.Volatile
Dim ret() As Variant
ReDim ret(1 To 1, 1 To (Application.Caller.Columns.Count))
Dim RetIdx&, i&, cell As Range
RetIdx = 1
For i = 0 To UBound(ranges)
For Each cell in Application.Range(ranges(i), ranges(i).End(xlToRight))
ret(1, RetIdx) = cell.Value
RetIdx = RetIdx + 1
Next
Next
For RetIdx = RetIdx To UBound(ret, 2)
ret(1, RetIdx) = vbNullString
Next
ConcatRanges = ret
End Function
For your example, you'd call it like this:
=ConcatRanges(Sheet1!A1, Sheet1!A2, Sheet1!A3)

VBA applying function to each cell in range

I need to write macro or function or whatever in VBA, what will apply a function with arguments (e.g. vlookup) on a rangeof cells. I thought it can be done by macro, but there I could not use arguments for vlookup, so I dont know any way how to do it. Is it possible?
For example:
I want to have this:
vlookup(A1;G1:H50;2;0) in cell B1 and
vlookup(A2;G1:H50;2;0) in cell B2 and so on, to e.g. B10
but I want to write formula only once and let other cells to be filled automaticaly.
Thanks a lot.
If I understand you correctly, here is one way (you'll have to change the delimiter to match your country settings, and adjust where you want the formula to go, I just put in B1:B10 as an example):
Sheet1.Range("B1:B10").Formula = "=vlookup(A1,$G$1:$H$50,2,0)"
This bit of code will write the formula to the range B1:B10 on sheet1, which has the same effect of putting the formula in the B1 and then "dragging" it down to B10. What makes this work is that Excel has the built in functionality of auto-incrementing a formula references based on whether or not the range is preceded by a $ symbol.
If a column reference has a $ in front, it will not increment as the formula is dragged across columns. If the $ is in front of the row reference, it will not increment as the formula is dragged down.
So looking back at my proposed formula, you can see that the A1 will increment as the formula is dragged to B2, B3, B4, etc...auto-incrementing the look up value to be cell A2, A3, A4, respectively. The look up range does not change at all because both the column and the row references are preceded by a $.
If you run the code I gave you, you'll see that you should have the expected results of only writing one formula, but changing the look up range through the built in auto incrementing functionality.
--------------------More edits based on comments--------------------
To do what you want, you don't need VBA at all (even though you initially requested a VBA / macro solution). You can put the formula in a cell and drag it down to how ever far down you want it to go. Please take a look at this link to see if it helps answer your questions:
How to fill data automatically in Excel
You could use Application.VLookup just like this following this example http://www.exceltrick.com/formulas_macros/vlookup-in-vba/:
Sub SetValues(columnToChange As String, columnToLookup As String, range As String, startColumn As Integer, endColumn As Integer)
For number = startColumn To endColumn Step 1
valueLookup = columnToLookup + CStr(number)
valueToChange = columnToChange + CStr(number)
Sheets("yourSheetName").Range(valueToChange).value = Application.VLookup(valueLookup, range, 2, 0)
Next number
End Sub
If you want to call them, create another subroutine without parameters that you can call from a button click for instance.
Sub DoStuff()
On Error GoTo ErrorHandler
Dim valueLookup as String
Dim valueToChange as String
Dim range as String
Dim firstColumn as Integer
Dim lastColumn as Integer
Label1:
valueLookup = InputBox("Enter the column to lookup")
valueToChange = InputBox("Enter the column to change")
range = InputBox("Enter the range of the lookup")
firstColumn = CInt(InputBox("Enter the first column number to lookup"))
lastColumn = CInt(InputBox("Enter the last column number to lookup"))
Call SetValues(valueToChange, valueLookup, range, firstColumn, lastColumn)
Exit Sub
ErrorHandler:
MsgBox("One value has an error in it.")
Resume Label1:
End Sub