VBA: Set range to columns in different worksheets - vba

I am trying to run the LinEst function through VBA. The problem that I am having is that my X-variables are in the same column but on different worksheets.
My question: Is it possible to combine these columns from the different sheets to one range?
Below is my attempt to code but it gets stuck on the Union part. I provided my sample as well.
Thank you in advance!
Sub FM()
Dim sResult As Worksheet
Set sResult = Sheets("Result")
Dim sY As Worksheet
Set sY = Sheets("Y")
Dim sX1 As Worksheet
Set sX1 = Sheets("X1")
Dim sX2 As Worksheet
Set sX2 = Sheets("X2")
Dim sX3 As Worksheet
Set sX3 = Sheets("X3")
Dim sX4 As Worksheet
Set sX4 = Sheets("X4")
Dim x() As Variant
ReDim x(1 To 4)
x(1) = sX1.Columns("A")
x(2) = sX2.Columns("A")
x(3) = sX3.Columns("A")
x(4) = sX4.Columns("A")
Dim rY As Range
Set rY = sY.Columns("A")
sResult.Range("B2").Value = Application.WorksheetFunction.LinEst(rY, x, True, True)(1, 4)
End Sub
Sample

In your update, x is an Array of Range objects but it needs to be an array of values from each respective range. That is almost certainly the mismatch error.
Resolving that, you'll need to fix your ranges, too, because it seems unlikely that you're using 4 million rows of data (Excel 2007+ has 1048576 rows per worksheet). We can use a method from this answer to help obtain the last row with data from a given column range.
This should get your x values and put them in an array known_x and the known_y array also, which you can use in your LineEst function.
Dim known_x() 'Will contain all of your x values
Dim known_y()
Dim i As Long
Dim rng As Variant
Dim val As Variant
Dim ws As Variant
Dim obs As Long
Dim SHEET_NAMES As String 'Comma-separated list of worksheets
SHEET_NAMES = "X1,X2,X3,X4"
'## Gets the size of the array needed to contain all of the values
For Each ws In Worksheets(Split(SHEET_NAMES, ","))
With ws
obs = obs + GetLastRow(.Columns(1))
End With
Next
ReDim known_x(1 To obs)
'## Dump the values in to the array
i = 1
For Each ws In Worksheets(Split(SHEET_NAMES, ","))
With ws
Set rng = .Range("A1:A" & GetLastRow(.Columns(1)))
For Each val In rng.Value
known_x(i) = val
i = i + 1
Next
End With
Next
'## Dump your y in to an array
With Worksheets("Sheet2")
Set rng = .Range("A1:A" & GetLastRow(.Columns(1)))
known_y = Application.Transpose(rng.Value))
End With
NOTE: If you are in fact using 4 million+ observations, then I think your known_y's parameter may be wrong, because that should be the same size as known_x's in the LinEst function, and you will need to add logic to ensure the arrays are the same size, etc.
NOTE: I've no idea what you're doing with (1, 4) at the end of your LinEst function call.

I don't want to put a useless answer, but if you play a bit with it, you will find something useful. And it produces some result in B2:
Option Explicit
Sub FM()
Dim sResult As Worksheet
Set sResult = Sheets(1)
Dim sY As Worksheet
Set sY = Sheets(2)
Dim sX1 As Worksheet
Set sX1 = Sheets(3)
Dim sX2 As Worksheet
Set sX2 = Sheets(4)
Dim sX3 As Worksheet
Set sX3 = Sheets(6)
Dim sX4 As Worksheet
Set sX4 = Sheets(5)
Dim x() As Variant
ReDim x(1 To 4)
x(1) = sX1.Cells(1, 1).Value
x(2) = sX1.Cells(2, 1).Value
x(3) = sX1.Cells(3, 1).Value
x(4) = sX1.Cells(4, 1).Value
Dim rY As Range
Set rY = sY.Range(sY.Cells(1, 1), sY.Cells(5, 1))
sResult.Range("B2").Value = Application.WorksheetFunction.LinEst(rY(1, 1), x(1), True, True)
End Sub
The problem is mainly in the way you refer to Arrays and Ranges. Check all of them again and you can make a workable solution.

Related

Excel VBA, Copying info to other sheet but with random names

I'm having a problem with my excel program. I want to make the names and the telephone numbers to paste at the other sheet, but names must be sorted randomly and the phone numbers must be the same. For Example at the first sheet i have Kalin Kalinov +22222222 and Martin Martinov +99119911 and at the other sheet after the copy paste action they must be like Martin Martinov +99119911 and Kalin Kalinov +22222222.
Sub GenerateNames()
Dim ssheet1 As Worksheet
Dim rnsheet As Worksheet
Set ssheet1 = ThisWorkbook.Sheets("Sheet1")
Set rnsheet = ThisWorkbook.Sheets("RandomNames")
ssheet1.Range("A3:A70").Copy rnsheet.Range("A3:A70")
ssheet1.Range("B3:B70").Copy rnsheet.Range("B3:B70")
End Sub
Add something like this, and apply it either on the source sheet or on the target sheet:
Range("C3").Formula = "=RAND()"
Range("C3").AutoFill Destination:=Range("C3:C70")
Range("A:C").Sort key1:=Range("C3"), order1:=xlAscending, Header:=xlYes
It creates a column of random values, used for sorting. You might want to delete it afterwards.
Sub randomName()
Dim ws As String, ws2 As String, rg As Range, rg2 As Range
Dim DataRange As Variant, i As Integer
Dim n As Integer, tmp As String
Dim nData As Integer
'== set by user
nData = 70 '== data size
ws = "sheet1": ws2 = "RandomNames" '== sheets name
Set rg = Sheets(ws).Cells(3, 1): Set rg2 = Sheets(ws2).Cells(3, 1) '=range with start row
'== Run
rg2.Resize(nData, 2).Value = rg.Resize(nData, 2).Value
DataRange = rg.Resize(nData).Value
For i = 1 To UBound(DataRange)
n = CLng(Rnd(i) * Second(Now) * 100) Mod UBound(DataRange) + 1
If i <> n Then tmp = DataRange(n, 1): DataRange(n, 1) = DataRange(i, 1): DataRange(i, 1) = tmp
Next i
rg2.Resize(nData) = DataRange: Set rg = Nothing: Set rg2 = Nothing
End Sub

How to fill an array with strings in VBA and get its lengh?

How to fill an array with strings in VBA and get its lengh?
For example two cells might contain this info:
A1: "test 1"
A2: "test 2"
Dim example As String
Dim arreglito() As String
example = Range("A2").Value
arreglito(0) = example
example= Range("A1").Value
arreglito(1)= example
MsgBox arreglito(0)
subscript out of range
Dim example As String
Dim arreglito() As Variant
example = Range("A2").Value
arreglito(0) = example
MsgBox arreglito(0)
subscript out of range
Here is a method of adding a single column range from the worksheet to a string array (transpose may have some size restrictions. 2^16 is it?).
Have used a line by Flephal to get the range into a string array in one step.
Sub AddToArray()
Dim arreglito() As String
Dim wb As Workbook
Dim ws As Worksheet
Set wb = ThisWorkbook
Set ws = wb.Worksheets("MySheet") 'change as appropriate
Dim srcRange As Range
Set srcRange = ws.Range("A1:A3")
arreglito = Split(Join(Application.Transpose(srcRange), "#"), "#")
MsgBox UBound(arreglito) + 1
End Sub
For more than one column transfer via a variant array:
Sub AddToArray2()
Dim arreglito() As String
Dim sourceArr()
Dim wb As Workbook
Dim ws As Worksheet
Set wb = ThisWorkbook
Set ws = wb.Worksheets("MySheet") 'change as appropriate
Dim srcRange As Range
sourceArr = ws.Range("A1:C3")
ReDim arreglito(1 To UBound(sourceArr, 1), 1 To UBound(sourceArr, 2))
Dim x As Long
Dim y As Long
For x = LBound(sourceArr, 1) To UBound(sourceArr, 1)
For y = LBound(sourceArr, 2) To UBound(sourceArr, 2)
arreglito(x, y) = CStr(sourceArr(x, y))
Next y
Next x
MsgBox UBound(arreglito, 1) & " x " & UBound(arreglito, 2)
End Sub
you can read entire excel range to array, its much faster than reading data from range cell by cell.
Sub testRerad()
Dim arr As Variant 'no brackets needed, I prefer to use variant
Dim numOfRows As Long, numOfCols As Long
arr = Sheets(1).Cells(1).Resize(10, 1).value 'arr will contain data from range A1:A10
'or
arr = Sheets(1).Range("A1").CurrentRegion.value 'arr will contain data from all continous data startig with A1
'get dimensions
numOfRows = UBound(a)
numOfCols = UBound(a, 2)
End Sub
be warned that this will always create multidimensional array (even if only 1 column) with dimensions 1 to y, 1 to x

Find the texts in Dynamic Range in another sheet

I am creating a VBA application that will find the text that I have entered in a certain range (Should be dynamic, in order for me to input more in the future). With that the entered texts in the range will look for the words in another sheet column:
Example:
And it will look for the words inputted in another sheet.
Dim Main as Worksheet
Set Main = Sheets("Sheet1")
Dim Raw2 as Worksheet
Set Raw2 = Sheets("Sheet2")
LookFor = Main.Range(D8:100)
Fruits = Raw2.Range("G" & Raw2.Rows.Count).End(xlUp).row
For e = lastRow To 2 Step -1
value = Raw2.Cells(e, 7).value
If Instr(value, LookFor) = 0 _
Then
Raw2.Rows(e).Delete
Honestly I am not sure how to proceed. And the mentioned code is just experiment. Desired output is to delete anything in sheet2 except for the rows that contain the words that I have inputted in the "Look for the words". Hope you can help me. Thank you.
This should do the trick :
Sub Sevpoint()
Dim Main As Worksheet
Set Main = Sheets("Sheet1")
Dim Raw2 As Worksheet
Set Raw2 = Sheets("Sheet2")
Dim LooKFoR() As Variant
Dim LastRow As Double
Dim i As Double
Dim j As Double
Dim ValRow As String
Dim DelRow As Boolean
LooKFoR = Main.Range(Main.Range("G8"), Main.Range("G" & Main.Rows.Count).End(xlUp)).Value
LastRow = Raw2.Range("G" & Raw2.Rows.Count).End(xlUp).Row
For i = LastRow To 2 Step -1
ValRow = Raw2.Cells(i, 7).Value
DelRow = True
'MsgBox UBound(LooKFoR, 1)
For j = LBound(LooKFoR, 1) To UBound(LooKFoR, 1)
If LCase(ValRow)<>LCase(LooKFoR(j, 1)) Then
Else
DelRow = False
Exit For
End If
Next j
If DelRow Then Raw2.Rows(i).Delete
Next i
End Sub

Transporting text from one worksheet to another with two Dynamic ranges- VBA Excel

I have two worksheets (one for input and another for output) and I'm trying to copy some information on cells along a row from the input to cells along a row on the output. My code stops if, on a separated list of ranges, there's no info. The code I'm using is like that right now:
Sub Txt_Manobra()
Dim x As Range
Dim i As Integer
Dim o As Integer
Dim p As Integer
Dim Txt1 As String
Dim Txt2 As Variant
For Each x In Worksheets("Formulario").Range("AK9:AK47").Cells
If x.Value <> "" Then Txt1 = x.Value
o = 8 + x.Count
For i = 1 To 7
p = 3 + i
Txt2 = Worksheets("Formulario").Range(o, p).Value
Worksheets("SdB pg1").Range(Txt1).Cells(1, i) = Txt2
Next i
Next x
End Sub
For each range value (x), it looks on the range txt1 (That is composed of only one row), and it should copy the values on range (D9:J9), one at a time and put on the range determined x (also only one row and with the same number of columns as D9:J9) then look on the next row (D10:J10) and so on.
I'm getting errors and I think this might be easier to do than I Think.
It's like that:
Input
And I want to tranfer to
Output
Each cell in the range "AK9:AK47" Contains a range like "P10:V10"
I haven't made it to work out to see if my "o" changes
If there are valid cell addresses in range AK9:AK47, then something like this should work for you. Note that using single letter variables is bad practice, and you can customize the code by adjusting the constants at the top.
Sub tgr()
Const sDestInfoCol As String = "AK"
Const lHeaderRow As Long = 8
Const lStartCopyCol As String = "D"
Const lFinalCopyCol As String = "J"
Dim wb As Workbook
Dim wsData As Worksheet
Dim wsDest As Worksheet
Dim rDestInfo As Range
Dim rDestTemp As Range
Dim lNumCols As Long
Set wb = ActiveWorkbook
Set wsData = wb.Sheets("Formulario")
Set wsDest = wb.Sheets("SdB pg1")
Set rDestInfo = wsData.Range(sDestInfoCol & lHeaderRow + 1, wsData.Cells(wsData.Rows.Count, sDestInfoCol).End(xlUp))
If rDestInfo.Row <= lHeaderRow Then Exit Sub 'No data
lNumCols = Columns(lFinalCopyCol).Column - Columns(lStartCopyCol).Column + 1
For Each rDestTemp In rDestInfo.Cells
With rDestTemp
If Evaluate("ISREF(" & .Text & ")") Then
wsDest.Range(.Text).Resize(1, lNumCols).Value = wsData.Cells(.Row, lStartCopyCol).Resize(1, lNumCols).Value
End If
End With
Next rDestTemp
End Sub

Excel VBA array of Selected Range

I know how to make two functions on each column (in this case TRIM and STRCONV to ProperCase
Dim arrData() As Variant
Dim arrReturnData() As Variant
Dim rng As Excel.Range
Dim lRows As Long
Dim lCols As Long
Dim i As Long, j As Long
Range("H2", Range("H2").End(xlDown)).Select
lRows = Selection.Rows.Count
lCols = Selection.Columns.Count
ReDim arrData(1 To lRows, 1 To lCols)
ReDim arrReturnData(1 To lRows, 1 To lCols)
Set rng = Selection
arrData = rng.Value
For j = 1 To lCols
For i = 1 To lRow
arrReturnData(i, j) = StrConv(Trim(arrData(i, j)), vbProperCase)
Next i
Next j
rng.Value = arrReturnData
Set rng = Nothing
Currently I'm trying to figure out how to add one more FOR which where I could gather more than one selection ranges for example:
Set myAnotherArray(0) = Range("H2", Range("H2").End(xlDown)).Select
Set myAnotherArray(1) = Range("J2", Range("J2").End(xlDown)).Select
For k = 1 To myAnotherArray.lenght
Because I'm copying and pasting whole script to make aciton on three columns. Tried already:
Dim Rng As Range
Dim Area As Range
Set Rng = Range("Range("H2", Range("H2").End(xlDown)).Select,Range("J2", Range("J2").End(xlDown)).Select")
For Each Area In Rng.Areas
Area.Font.Bold = True
Next Area
Even tried to Union range but I failed. Any sugesstions?
And as always... Thank you for your time!
I found a way you could use to perform work on those ranges, refer to the code below:
Sub DoSomethingWithRanges()
Dim m_Worksheet As Excel.Worksheet
Dim m_Columns() As Variant
Set m_Worksheet = ActiveSheet
' fill all your columns in here
m_Columns = Array(2, 3, 4)
For Each m_Column In m_Columns
' the area being used ranges from the second until the last row of your column
With m_Worksheet.Range(m_Worksheet.Cells(2, m_Column), m_Worksheet.Cells(m_Worksheet.UsedRange.Rows.Count, m_Column))
' do things with range
.Font.Bold = True
End With
Next m_Column
End Sub
In the variant array m_Columns you can add all the columns you want. Only downside is that in my example you have to use numbers to specify columns instead of "H". However, you don't have to worry about the row-indexes, since the area automatically ranges from the second to the last used row.