VBA nested for loop won't Run - arrays

Hi I'm working on a macro in VBA for excel. I have a nested for loop in my code as seen below. The second loop does not run; even a MsgBox() command within the second loop doesn't result in any action and the program just seems to skip over the nested loop with no reported errors.
In plain English this nested loop should:
1) Take the string from the i entry in the array categories_string (first for loop).
2) iterate through the 300+ rows in column "AE" in the excel file (second for loop, "length" is the length of the column of data in "AE")
3) look for string matches and add 1 to the corresponding entry in the categories_value array which is populated with variables set to 0 (the if statement).
For i = LBound(categories_string) To UBound(categories_string)
For p = 1 To p = length
If Worksheets("sheet1").Cells(p + 2, "AE").Value = categories_string(i) Then
categories_value(i) = categories_value(i) + 1
End If
Next
Next

Change
For p = 1 To p = length
to
For p = 1 To length
Should fix you right up.
You may want to consider Scott Cranner's comment as well, especially if your categories_string is large and length is large. Or, just do it for the practice

Related

Excel VBA - Add an array to a dictionary and search if it exists

Within a loop I would like to write values to a cell only if a string combination has not already been gone through.
So I am trying to create a dictionary containing an array (the combination of two string variables) and then to check if this combination already exists in the dictionary. My code is the following and I get the “Invalid procedure call or argument” error at the first line. Could you please help me solve this?
…
If Not my_dict.exists(arr) Then
With my_sheet.Cells(x, COL_DOC)
.Value = string1
End With
arr = Array(string1, string2)
my_dict.Add k, arr
k = k + 1
End If
…

Filling a row and columns of a ndarray with a loop

I'm starting with Python and I have a basic question with "for" loop
I have two array which contains a values of a same variables:
A = data_lac[:,0]
In the first array, I have values of area and in the second on, values of mean depth.
I would like to find a way to automatize my calculation with different value of a parameter. The equation is the following one:
g= (np.sqrt(A/pi))/n
Here I can calculte my "g" for each row. Now I want to have a loop with differents values of "n". I did this:
i=0
while i <= len(A)-1:
for n in range(2,6):
g[i] = (np.sqrt(A[i]/pi))/n
i += 1
break
In this case, I just have one column with the calculation for n = 2 but not the following one. I tried to add a second dimension to my array but I have an error message saying that I have too many indices for array.
In other, I would like this array:
g[len(A),5]
g has 5 columns each one calculating with a different "n"
Any tips would be very helpful,
Thanks
Update of the code:
data_lac=np.zeros((106,7))
data_lac[:,0:2]=np.loadtxt("/home...", delimiter=';', skiprows=1, usecols=(0,1))
data_lac[:,1]=data_lac[:,1]*0.001
#Initialisation
A = data_lac[:,0]
#example for A with 4 elements
A=[2.1, 32.0, 4.6, 25]
g = np.zeros((len(A),))
I believe you share the indexes within both loops. You were increasing the i (index for the upper while loop) inside the inner for loop (which index with n).
I guess you have A (1 dim array) and you want to produce G (2 dim array) with size of (Len(A, 5))
I am not sure I'm fully understand your require output but I believe you want something like:
i=0
while i <= len(A)-1:
for n in range(2,6):
g[i][n-2] = (np.sqrt(A[i]/pi))/n # n-2 is to get first index as 0 and last as 4
i += 1 # notice the increace of the i is for the upper while loop
break
Important - remember that in python indentation means a lot -> so make sure the i +=1 is under the while scope and not indent to be inside the for loop
Notice - G definition should be as:
g = np.zeros((len(A),4), dtype=float)
The way you define it (without the 4) cause it to be 1 dim array and not 2-dim

Are my arrays incompatible?

I am trying to loop through an array that contains split strings, done via this line:
repHolder() = Split(rep, ",")
That's all fine and good, however, when I try to loop through this repHolder() array via a for loop, I am met each time with a subscript out of range error.
This makes no sense to me. When I step through the array it fails on the first element every time; this line:
If repHolder(j) = counter Then
I tried setting j to 0 and 1, both of which failed on the first sequence of the loop. This suggests to me because the array doesn't have a defined size; that I cannot loop through it this way, but that still makes little sense to me as it is still filled with elements.
Here is the entire code block of what I am trying to do:
Dim repHolder() As String
Dim strHolder() As String
Dim counter As Variant
Dim j As Integer
For Each rep In repNames()
repHolder() = Split(rep, ",")
Next rep
For Each rangeCell In repComboRange
k = 1
Do
If rangeCell.Value = repCombos(k) Then 'At this point, if rangecell = repcombos(k)
Range(rangeCell, rangeCell.End(xlToRight)).Copy
strHolder() = Split(rangeCell.Value, "/")
For Each counter In strHolder()
Stop
For j = 1 To 17
If repHolder(j) = counter Then
You are looping through repNames() and setting this new array via split (over and over again for each repName element...)
For Each rep In repNames()
repHolder() = Split(rep, ",")
Next rep
Every iteration of this loop resets repHolder() to a split of the rep element dropping whatever values were just set in that array in the previous iteration. So once it's done only the last element of RepNames() has been split into the repHolder() array.
For instance, if RepNames() looks like:
Element 0: "james,linda,mahesh,bob"
Element 1: "rajesh,sam,barb,carrie"
Element 2: ""
Then after all this iterating your repHolder array is going to be empty because there is nothing in the final element.
Stick a breakpoint (F9) on you For Each rangeCell In repComboRange line and look at your Locals pane in VBE. Check out the values that are stored in your repHolder() array at that point in time. I suspect there will be nothing in there.
The other oddball here is that you are looping 1 through 17. repHolder() will be a 0-based array so that should be 0 through 16. But... even that is nonsense since this really only makes sense as a For Each loop (or to use the uBound(repHolder) to determine how many times to loop:
For Each counter In strHolder()
Stop
For each repHolderElem in repHolder
If repHolderElem = counter Then
....
Next repHolderElem

Subscript out of range when trying to get last item of an Array

For example, I have a string A-456-BC-123;DEF-456;GHI-789. And I need to search for second part:DEF-456 with keyword 456. The potential problem here is that the first part A-456-BC-123 also has the keyword 456. Currently my logic is that, split the string first using ;, split each of it again using -, get the last item of this Array, search keyword 456. Another thing is that I don't want to do a full keyword match like DEF-456, I only want to use 456 as keyword to locate DEF-456, in other words, 456 should be the last segment of the string I want.
Here are my codes:
FirstSplit= split("A-456-BC-123;DEF-456;GHI-789",";")
For each code in FirstSplit
SecondSplit = split(FirstSplit,"-")
'get Array Count
Count = Ubound(SecondSplit)
'get the last item in Array
If SecondSplit(Count-1) = "456" Then
'doing something
End if
Next
Currently, an error will generate at SecondSplit(Count-1), saying that "Subscript out of range: '[number: -1]'"
Could someone tell me how to fix it?
The real problem is here:
SecondSplit = Split(FirstSplit, "-")
You should be splitting your element which you've stored in variable code from your For Each loop. By trying to split an array you should be getting a Type Mismatch error, but perhaps vbscript is forgiving enough to attempt and return a 0 element array back or something. Anyway:
SecondSplit = Split(Code, "-")
Also, to look at the last element just use:
If secondSplit(Ubound(SecondSplit)) = "456" Then
Subtracting 1 from the ubound would get you the second to last element.
You don't need to split it twice - what you're looking for is Right():
FirstSplit = split("A-456-BC-123;DEF-456;GHI-789",";")
For each code in FirstSplit
If Right(code, 3) = "456" Then
' do something
End If
Next
Though this would also match an entry like ABC-1456. If the - symbol is a required delimiter, you'd have to say If Right(code, 4) = "-456".

files comparison

I'm trying to compare 2 txt files to check files are equals otherwise, get the output and give difference (say that there are a diff line x)
I'm trying as follows:
fid1 = fopen(file_1, 'r');
fid2 = fopen(file_2, 'r');
lines1 = textscan(fid1,'%s','delimiter','\n');
lines2 = textscan(fid2,'%s','delimiter','\n');
lines1 = lines1{1};
lines2 = lines2{1};
fclose(fid1);
fclose(fid2);
tf = isequal(lines1,lines2); % this gives 0 or 1
I would like when the value is 0 (files are different) to localize the diff and give line where files are different or print content of difference.
You essentially want to compare each element of the two cell arrays you have, not the whole cell arrays. You could do that with a loop in most languages, but of course MATLAB has many ways to avoid loops. Here, it is cellfun:
cellfun(#isequal,lines1,lines2)
(I left out the part where, if the two cell arrays are of unequal size, you have to shorten the longer one.) Then, find is useful for finding the first (or all) occurrence(s) of a certain value in any vector.

Resources