Apache poi calculating cell address - apache-poi

How to get cell address when cell is null?
lets say i have the following excel
A B C D
1 x x x x
2 x x x
3 x x x x
When I am iterating inside a row over columns
something like:
for (i in 0 until lastCellNum) {
val cell = row.getCell(i)
if (cell != null){
println(cell.address)
} else {
println("cell data is missing at address: "+ //address_calculation)
}
}
How to print this?:
"cell data is missing at address: C2"

If I create a celladdress by hand it will calculate it:
CellAddress(rowIndex,colIndex).formatAsString

Related

array from continuous data?

I have a quite difficult problem that i cant wrap my head around.. hope you can help me!
Lets say my data is in A1:G1 for example:
A1 B1 C1 D1 E1 F1 G1
X X 0 X X X 0
or
Y X X X X Z X
The thing i would need to come up with is how to get array from this data according to the X, BUT if like in example 1 there is 2 times X in the beginning and 3 x next to each other so the array should come out like {2;2;0;3;3;3;0} so i want the array to be 7 long and the array should show the x as number how many are next to each other.
example 2 should come out like {0;4;4;4;4;0;1}
if you can figure this out would really help me alot!
Edit:
Trying to give out better, more bigger picture of what i mean..
if data is :
A B C
1 X X
2 X X
3 X
it should come out as
A B C
1: 2 4 0
2: 0 4 2
3: 1 0 0
or in array {2\4\0;0\4\2;1\0\0}
on B1 and B2 there should be 4 because the formula should count horizontal but also vertical continuum. I tried to use usmanhaqs formula but i was not able to modify it so the count resets on every line.
Real size of the table is 7 times 7 cells.
I will use the array with another array (scoreboard which is also 7 times 7 cells, and has numbers 1, 2 or 3 on every cell) using sumproduct and it will give out the points of that player.
I appreciate your efforts on helping out a newbie learner on vba :)
For a formula solution, I can only come up with one for the special case where you have just X's and zeroes (example 1) so far:
=SUM(IF(A1:G1<>"X",0,INDEX(FREQUENCY(IF(A1:G1="X",COLUMN(A1:G1)),IF(A1:G1<>"X",COLUMN(A1:G1))),N(IF({1},SUBTOTAL(2,OFFSET(A1,0,0,1,COLUMN(A1:G1)))))+1,1)))
entered as an array formula using CtrlShiftEnter
I have wrapped it in a SUM function to demonstrate that it generates an array which can be passed to another function (result: 13) or it can be array-entered across several cells:
You can test this code
Function get_array(r As Range, match_chr As String)
Dim check_val
Dim array_value
array_value = "{"
For i = 1 To r.Count
check_value = r.Item(i)
If (check_value = match_chr) Then
j = i + 1
Do While (j <= r.Count) And (check_value = r.Item(j))
j = j + 1
Loop
array_value = array_value & WorksheetFunction.Rept(j - i & ", ", j - i)
i = j - 1
Else
array_value = array_value & "0, "
End If
Next
array_value = Left(array_value, Len(array_value) - 2) & "}"
get_array = array_value
End Function
You can use it as below
EDIT
find below another function to return an array of values that can be used in the formulae
Function get_number_array(r As Range, match_chr As String)
Dim check_val
Dim array_value
Dim number_array(1 To 50) As Long
For i = 1 To r.Count
check_value = r.Item(i)
If (check_value = match_chr) Then
j = i + 1
Do While (j <= r.Count) And (check_value = r.Item(j))
j = j + 1
Loop
For k = 1 To j - i
number_array(i + k - 1) = j - i
Next k
i = j - 1
Else
number_array(i) = 0
End If
Next
get_number_array = number_array
End Function
You have to use it same as the previous one, but it will return excel array.

elegant way to iterate & compare in Spark DataFrame

I have a Spark DataFrame with 2 columns: C1:Seq[Any] and C2:Double. I want to
Sort by length of C1.
For each element c1 in C1, compare with every other element in C1 that is longer than c1.
2.1 If c1 is contained in an another element cx, then compare c2 with c2x.
2.2 If c2 > c2x, then filter out (c1x, c2x).
Is there an elegant way to achieve this?
Sample Input:
C1 C2
ab 1.0
abc 0.5
Expected output:
C1 C2
ab 1.0
Contain = subset. e.g. ab is contained in abc.
I have a Spark DataFrame with 2 columns: C1:Seq[Any] and C2:Double
val rdd = sc.parallelize(List(("ab", 1.0), ("abc", 0.5)))
Sort by length of C1.
val rddSorted = rdd.sortBy(_._1.length).collect().distinct
For each element c1 in C1, compare with every other element in C1 that is longer than c1.
2.1 If c1 is contained in an another element cx, then compare c2 with c2x.
2.2 If c2 > c2x, then filter out (c1x, c2x).
val result = for(
(x, y) <- rddSorted;
(a, b) <- rddSorted.dropWhile{case(c,d) => c == x && d == y};
if(a.contains(x) && a.length > x.length && y > b)
)yield (x, y)
Thats all. You should get what you are looking for

Can I use SUMPRODUCT to accomplish this?

Need to sum a range based on if a value is in a column and one of a set of values is in another column, or vice versa.
e.g. I have The following table:
A B C D
M C C 1
F C C 2
S N C 3
S N N 4
M - C 5
N C C 6
M C N 7
If (Column A contains "M" or "S") AND ((Column B contains "C" AND Column C Contains "C" Or "N" Or "-") OR (Column C contains "C" AND Column B Contains "C" Or "N" Or "-")) Then Sum column D
So from my table my results would be
1 + 3 + 5 + 7 = 16
You can use SUMPRODUCT like this:
=SUMPRODUCT(ISNUMBER(MATCH(A2:A10,{"M","S"},0)*MATCH(B2:B10&"^"&C2:C10,{"C^C","C^N","C^-","N^C","-^C"},0))+0,D2:D10)
MATCH is used to check for both valid possibilities in column A and then all 5 possibilities for concatenated columns B and C - if those conditions are met then column D will be summed. Extend column ranges as required but preferably don't use whole columns
.....or shorter with SUMIFS like this:
=SUM(SUMIFS(D:D,A:A,{"M";"S"},B:B,{"C","C","C","N","-"},C:C,{"C","N","-","C","C"}))
For that version you can use whole columns with no loss of efficiency.
Note that in this version all the separators in the array constants are commas EXCEPT for the semi-colon in {"M";"S"} which needs to be that way
I would add a fifth column with a condition for the current line returning the value in D if all conditions are true or 0 otherwise.
=Iif(AND(Or($A1 = "M", $A1 = "S"),OR(AND($B1 = "C",Or($C1 = "C",$C1 = "N",$C1 = "-")), AND($C1 = "C",OR($B1 = "C",$B1 = "N",$B1 = "-")))),$D1,0)
Then in a cell somewhere write =sum($E:$E). With your example, I get 16, as intended.

How do I solve two equations where one equation has a variable that takes a range of values?

Two equations ---
c + w + u = 50;
c-w/4 = 39
In the above, 'u' takes integer values from 0 to 11. (Why/How the 11? 11 = 50-39).
I need to output a table of values for c and w for each value of u starting with u = 0. The corresponding value of u must also appear across each row of values for c and w.
How do I write a VBA code for this?
Many thanks in advance!
Do a little algebra first:
c-w/4 = 39
c = 39+w/4
c+w+u = 50
39+w/4+w+u = 50
w/4+w+u = 50-39
w/4+w = 11-u
1.25*w = 11-u
w = (11-u)/1.25
Put the u values in column A. In B1 enter:
=(11-A1)/1.25
and copy down. In C1 enter:
=39+B1/4
and copy down.
The w values are in column B and the c values are in column C.

Excel: if any field in a row is not null, set the cell in the first column to an incrementing row number?

I'm trying to create a formula that will have the effect of automatically adding an incremental row number to the first column of my spreadsheet when any data is entered in any column of the row.
So for example, if my table looks like this:
a b c d e f
1 # x x x x x
2 # x x x x x
3 # x x
4 # x
5 # x
I would like the 'a' column to read:
0
1
2
3
4
And if I added more data in any column, e.g.:
a b c d e f
1 # x x x x x
2 # x x x x x
3 # x x x
4 # x x
5 # x x
6 # x
7 # x
It would then automatically up the index row 'a' to read as:
0
1
2
3
4
5
6
I hope this makes sense! Any help, or even just a tutorial to point me in the right direction would be so appreciated!
Here is the answer:
=if(counta(B2:F2)>0,A1+1,"")
The above works! Thanks to Alan Whitelaw for the answer, only posting this for others as it has the fixed syntax.
If I undersand corectly, and the sheet will always be filled in "in order" down the rows this should work
=if(counta(B2:D2)>0,A1+1,"")
Pop this in A2, and where B2:D2 is the rest of the row to test.
Excel's counta() counts non-blank cells.

Resources