I am trying to call a multidimensional table from one function to another one but I get the error :
Sub or Function not defined
here is what I tried :
Public Function update()
Public tabPerformance(11, 16) As Long
If (Worksheets("Feuil1").Range("E3").Value = "Performance") Then
For j = 0 To j = 1
For i = 0 To i = 1
For k = 3 To 5
For l = 6 To 8
tabPerformance(j, i) = Cells(l, k).Value
MsgBox tabPerformance(j, i)
Next l
Next k
Next i
Next j
End If
If (Worksheets("Feuil1").Range("E3").Value = "Inflation") Then
For j = 0 To j = 1
For i = 0 To i = 1
For k = 3 To 5
For l = 6 To 8
tabInflation(j, i) = Cells(l, k).Value
MsgBox tabInflation(j, i)
Next l
Next k
Next i
Next j
End If
and this is the function where I want to call the tabPerformance Table :
Public Function recap()
Dim tabPerformanceCells(11, 16) As Long
If (Worksheets("Feuil1").Range("E3").Value = "Performance") Then
For j = 0 To j = 1
For i = 0 To i = 1
For k = 3 To 5
For l = 6 To 8
Cells(l, k).Value = tabPerformance(j, i)
MsgBox Cells(l, k).Value
Next l
Next k
Next i
Next j
End If
I need to know how to properly call the tabPerformance from anywhere i want.
There are four things you should know about when developing VBA code.
Put 'Option Explicit' at the start of each Module/Class'. This will make sure that you don't get errors because of incorrect syntax of misspelled variable names.
In the VBA IDE if you press F1 when the cursor is on a VBA keyword this will bring up the MS Help Page for that feature in VBA. This should be your first port of call for any errors you see. Try this for the F'or' keyword and you will see that your syntax for the For loop is incorrect.
Before you run any code make sure you compile the whole project so that you can find errors that are not detected by Option Explicit. (Debug.Compile Project)
Install the fantastic RubberDuck addin for VBA. Its free software. RubberDuck will help keep your code nicely indented, allow you to rename things safely and produce 'Code Inspections' which is where a stricter analysis of the VBA code is done and advice is given on how to write your code more safely.
Related
Dim a As Integer
a = 0
For i = 4 To i + 1
Set xRange = Sheets("sayfa4").Rows(i)
For j = 1 To 10
If Sheets("sayfa4").Cells(i, j) > 0 And Sheets("sayfa4").Cells(i, j) = Application.WorksheetFunction.Min(xRange) Then
a = a + 1
Sheets("sayfa4").Cells(i, j).ClearContents
Sheets("sayfa4").Cells(15 + a, 1) = i
Sheets("sayfa4").Cells(15 + a, 2) = j
i = j - 1
End If
Next j
Next i
i don't get any errors or something i just can't execute it nothing happens on excel sheet can you help me guys what is the problem
when i try with F8 it shows "i = empty"
my main problem is declaring the next i actually
when i choose a cell(i,j) and printing the value of it
my next i should be j and after i should start to search min value of j row and it turns out next i
I tryed to understand your logic and rewrote the code:
Option Explicit
Sub test()
Dim a As Integer
Dim i As Long, j As Long
Dim xRange As Range
a = 0
i = 4
For i = 4 To i + 1
Set xRange = Sheets("sayfa4").Rows(i)
For j = 1 To 10
If Sheets("sayfa4").Cells(i, j) > 0 And Sheets("sayfa4").Cells(i, j) = Application.WorksheetFunction.Min(xRange) Then
a = a + 1
'Sheets("sayfa4").Cells(i, j).ClearContents
Sheets("sayfa4").Cells(15 + a, 1) = i
Sheets("sayfa4").Cells(15 + a, 2) = j
Exit For
'i = j - 1
End If
Next j
Next i
End Sub
If you are looking for the minimum value of a selection, this code should solve your issue
This statement is meaningless
For i = 4 To i + 1
this is because i is uninitialized or zero and so the loop is really For i=4 to 1 which will be ignored.
If you do not know how many times to iterate use a Do Loop instead. Only use For for fixed iterations and do not alter the iteration variable inside the loop.
If you want to stop the loop use Exit For, or Exit Do and if you want to end the function or subroutine processing use Exit Function or Exit Sub.
To skip to the next iteration in VBA you would use an If structure, since it does not have a continuation keyword like other languages have. (thanks #BigBen)
I have two lists with the same set of data (e.g. A, B, C, D), and I want to be able to create a list of combinations that exclude the same data twice (e.g. A/A, B/B, etc) and reversed sets (i.e. A/B means I don't want B/A)
I'm using Excel for Mac 2011, if that matters.
Edit:
Ideally I would like to use Tables instead of inputting individual data pieces because the actual list is very long
The following tables are named T_TESTA and T_TESTB:
Edit 2:
Both solutions presented to me below are working perfectly, but I'm only allowed to pick one. So I'm picking the one based on streamlining an issue that came up for me that's entirely unrelated to the code itself. The other solution is slightly more elegant for presenting the data together in a list.
Try this short macro:
Sub Kombo()
arr = Array("A", "B", "C", "D")
k = 1
For i = 0 To 2
For j = i + 1 To 3
Cells(k, 1) = arr(i) & arr(j)
k = k + 1
Next j
Next i
End Sub
The loops are configured to create combinations rather than permutations.
EDIT#1:
In this version of the code we get the values from cells rather than an internal array. I assume the values are in E1 through E4:
Sub Kombo2()
Dim arr(0 To 3) As Variant
For i = 0 To 3
arr(i) = Range("E" & i + 1).Value
Next i
k = 1
For i = 0 To 2
For j = i + 1 To 3
Cells(k, 1) = arr(i) & arr(j)
k = k + 1
Next j
Next i
End Sub
The results are still displayed in column A
Here are a couple of formulas I worked out for Google Sheets here and translated back into Excel:
=IFERROR(INDEX(A:A,CEILING((2*COUNTA(A:A)-1-SQRT((2*COUNTA(A:A)-1)^2-8*ROW()))/2,1)),"")
and
=IFERROR(INDEX(A:A,COUNTA(A:A)+ROW()-((2*COUNTA(A:A)-1)*CEILING(((2*COUNTA(A:A)-1)-SQRT((2*COUNTA(A:A)-1)^2-8*ROW()))/2,1)-CEILING(((2*COUNTA(A:A)-1)-SQRT((2*COUNTA(A:A)-1)^2-8*ROW()))/2,1)^2)/2),"")
I'm trying to put one loop called j into another called i. In one of the ways I've tried the j loop end before the i loop and copy the same number each time because the i loop is no advancing.
For i = 2 To lastRowK
For j = 5 To 500
If Worksheets(1).Cells(i, 5).Value = 7 Then
Worksheets(2).Cells(j, 6).Value = Worksheets(1).Cells(i, 1).Value
Next j
Next i
In the other option, I've tried to put a conditional for the Next j, but it gives to me a compile error: Next without for.
For i = 2 To lastRowK
For j = 5 To 500
If Worksheets(1).Cells(i, 5).Value = 7 Then
Worksheets(2).Cells(j, 6).Value = Worksheets(1).Cells(i, 1).Value
If KRData.Cells(i, 5).Value = 7 Then _
Next j
Next i
The third option I've tried is to put both of next in the conditional, but it returns a compile error: expected list separator or end of the statement.
For i = 2 To lastRowK
For j = 5 To 500
If Worksheets(1).Cells(i, 5).Value = 7 Then
Worksheets(2).Cells(j, 6).Value = Worksheets(1).Cells(i, 1).Value
If KRData.Cells(i, 5).Value = 7 Then _
Next j AND Next i
Also, the end if or else are not working.
Make sure your To value lastRowK is set before the start of the loop. If its value is less than the initial value, in your case 2, the expression will evaluate false and terminate the loop.
For i = 0 To 3
Next i
Will loop until i = 4. It will then terminate the loop and resume execution at the next line of code following the Next statement.
For i = 2 To 1
Next i
In this example the loop will immediately terminate and advance to the the first line of code preceding the next statement. I’d be willing to bet if you put a breakpoint at the initialization of your loop, and the checked the local variables in the tools menu, you’d see that lasRowK has a value of Empty or less than equal to 1.
Can anyone help me? (I am new in VBA and i also got help to create this macro)
I created a macro for a file and first it was working fine, but today I've been opening and restarting the file and macro hundreds of times and I'm always getting the following error: Excel VBA Run-time error '13' Type mismatch
I didn't change anything in the macro and don't know why am I getting the error. Furthermore it takes ages to update the macro every time I put it running (the macro has to run about 700 rows).
The error is in the between ** **.
VBA:
Private Sub Worksheet_Change(ByVal Target As Range)
Dim i As Integer
Dim j As Integer
Dim z(8) As Integer
Set ws = ThisWorkbook.ActiveSheet
For i = 6 To ws.Cells.SpecialCells(xlCellTypeLastCell).Row - 3
If Not ws.Rows(i).Hidden = True Then
For j = 0 To 8
If Not ws.Cells(i, j + 5) = "" Then
** z(j) = z(j) + ws.Cells(i, j + 5) **
End If
Next j
End If
Next i
Application.EnableEvents = False
For j = 0 To 8
ws.Cells(ws.Cells.SpecialCells(xlCellTypeLastCell).Row - 2, j + 5) = z(j)
Next j
Application.EnableEvents = True
End Sub
ws.Cells(i, j + 5) at a particular point does not contain a value that can be added to z(j). It's probably blank or doesn't contain a number.
One fix would be to write
On Error Resume Next 'switch off error handling
z(j) = z(j) + ws.Cells(i, j + 5)
On Error Goto 0 'the idiomatic way of switching the default error handling back on
Effectively then, your macro will not attempt to add a non-numeric value to z(j).
But solving the problem this way is a bit like using a sledgehammer to crack a nut: perhaps it's worth investigating the contents of the cell that's causing the error, and programming around that more elegantly.
Also, I question why this needs to be in VBA in the first place. Really you're doing something that excel can do in normal calculation. (Consider SUMIF and SUMIFS) Failing that, it would be quicker if you used a VBA Function rather than responding to change events.
In addition to what #Bathsheba mentioned, you might also want to consider declaring variables before using them to avoid problems. I wasn't able to run your code because Excel wouldn't know how to handle Z() and thought of it as a UDF. Try the following and let me know if this solves the problem:
Option Base 0
Option Explicit
Sub tmpTest()
Dim ws As Worksheet
Dim i As Long, j As Integer
Dim z(0 To 8) As Double
Set ws = ThisWorkbook.ActiveSheet
For i = 6 To ws.Cells.SpecialCells(xlCellTypeLastCell).Row - 3
If Not ws.Rows(i).Hidden = True Then
For j = 0 To 8
If Not ws.Cells(i, j + 5) = "" Then
z(j) = z(j) + IIf(VarType(ws.Cells(i, j + 5).Value) = vbError, 0, ws.Cells(i, j + 5).Value)
End If
Next j
End If
Next i
Application.EnableEvents = False
For j = 0 To 8
ws.Cells(ws.Cells.SpecialCells(xlCellTypeLastCell).Row - 2, j + 5) = z(j)
Next j
Application.EnableEvents = True
End Sub
I need some help with some VBA. The code below sorts a bunch of data which is spread horrizonally then apends them vertically which I have posted below:
Sub Test()
Application.ScreenUpdating = False
countrow = ActiveSheet.UsedRange.Rows.Count
countcolumn = ActiveSheet.UsedRange.Columns.Count
numberofiterations = countcolumn / 6
MsgBox "Number of Rows is" & Str(countrow)
MsgBox "Number of Column is" & Str(countcolumn)
ActiveSheet.Select
a = 1
b = 1
c = 6
d = 1
While n < numberofiterations
Range(Cells(a, b), Cells(countrow, c)).Select
Selection.Copy
Sheets(2).Select
ActiveSheet.Cells(d, 1).Select
Sheets(2).Paste
Sheets(1).Select
b = b + 6
c = c + 6
d = d + countrow
n = n + 1
Wend
End Sub
It runs ok once but when running it for the second time it itteraits through to the line:
While n < numberofiterations
I can't find the reason why it drops out the loop the second time. Any help will be apriciated
Thanks,
A few things to consider:
1) Please initialize the value of n. That is, before you start your loop, set
n = 0
explicitly. If you later add other code that happens to set n to some value, you will not get the result you expect
2) When you say
countrow = ActiveSheet.UsedRange.Rows.Count
Range(Cells(a, b), Cells(countrow, c)).Select
You will not get a selection all the way to the bottom of the range IF THE USED RANGE DIDN'T START IN ROW 1. If UsedRange = $Q1:Z20, then UsedRange.Rows.Count = 10, not 26!
This second point is probably not your problem today - but I wanted to point it out as it will bite you another time.
3) I am a huge fan of writing
Option Explicit
at the top of every module. It forces you to be thoughtful about every variable you create, and more likely will make you remember to initialize variables as well. In general it's good practice, and should be right up there on your list with "initialize right before you use".