Turning filled out combo box into a number? - combobox

I have 4 combo boxes where you can select an employee. I want to get a value between 0 and 4 to show how many combo boxes have employees in them. I'll be using this number to automatically calculate length of job times. I think I'm all wrong in my approach. I think I need to use str or val.
I'm starting with:
Private Sub ATeamLeaderMon_Change()
If ATeamLeaderMon Is Null Then Me.AMaidMonTotal = Me.AMaidMonTotal + 0
If AMaidMonTotal Is Not Null Then Me.AMaidMonTotal = Me.AMaidMonTotal + 1
End Sub

Try with:
Me!AMaidMonTotal.Value = Abs(Not IsNull(Me!Combo1.Value)) + Abs(Not IsNull(Me!Combo2.Value)) + Abs(Not IsNull(Me!Combo3.Value)) + Abs(Not IsNull(Me!Combo4.Value))

Related

Effectively using 2D VBA Array variable and fetch whenever required

I am trying to develop a mechanism where I can store all the values in 2D array for below table.
Below is the code that I have developed, just to store values.
Sub temp()
Dim QtyArray(4, 11) As Integer, rw As Integer, col As Integer
For rw = 0 To 4
For col = 0 To 11
QtyArray(rw, col) = Cells(rw + 2, col + 3).Value
MsgBox QtyArray(rw, col)
Next col
Next rw
End Sub
I want to apply logic as per below:
First identify columns where COUNTA is 1 (highlighted in red) and move 1 qty of stock from that store to another store where COUNTA > 2, priority would be in order from store A to L. For example, first store with COUNTA=1 is store D, and it has qty 2. So I want to move these 2 qty to store E (not store C because it has already 1 qty, also H has 2 qty.)
If the COUNTA of any store's qty is zero, nothing to be done.
I want to fetch separate report as per below format, showing how the stock is being moved across store as per logic rule 1.
Output:
Explained in previous section.

ISBLANK(...) = FALSE even thought the cell is blank in google sheet

Hi everyone,
I have 2 tables, 3rd column for Table 1 is Value 1 and 3rd column for Table 2 is Value 2. I combined these 2 tables by expanding both tables first so that all the columns are aligned as shown in the screenshot above (Column E to Column H).
The formula in all the yellow cells are:
Cell E4 : =QUERY(A4:C10,"Select A,B,C,' ' label ' ' 'Value 2' ")
Cell E12 : =QUERY(A12:C20,"Select A,B,' ',C label ' ' 'Value 1' ")
Cell K7 : =QUERY({E5:H10;E13:H17},"Select * where Col1 is not null",0)
Cell P7 : =ArrayFormula(IF(ISBLANK(M7:M12),100,M7:M12))
In column P, I want to return 100 as Value 1 if the cells in Column M is blank. So by right I should get 2,34,55,100,100,100 in column P but right now the formula still return 3 blank cells.
I suspect that is because the QUERY function that I used before which make the cell is not blank although it seems like still a blank cell. May I know is there any trick that I can use to find the blank cells in column M and column N (preferably don't touch the QUERY formula) since ISBLANK() is not working in this case?
Any help or advise will be greatly appreciated!
Edited
makes sense. you cant use ISBLANK because cell is not blank. remember that QUERY inserted an empty space.
try:
=ARRAYFORMULA(IF(ISBLANK(TRIM(M7:M12)), 100, M7:M12))
ISBLANK is so sensitive that it will detect even residue from TRIM
update:
=ARRAYFORMULA(IF(TRIM(M7:M12)="", 100, M7:M12))

VBA Excel Using an array element to reference a cell in a Word document's table

I'm using an Excel userform to push data entered on the form into a Word Document. The Word document has several tables and the data from the form textbox controls needs to go into specific cells on the Word document. There are 15 checkboxes with 15 matching textboxes on the Excel form, so I figured the easiest way to handle it is with an array so I could loop through it.
Addressing the checkboxes (the Program array) isn't an issue because they're named "chkbox1-chkbox15" and there are matching Content Controls in the Word table tagged chkbox1-chkbox15, so that loop works properly.
The problem is with the textboxes' text. The cells the data needs to go in is kind of all over the place and I don't have the luxury of altering the table layout. So I figured I'd create a 15-element array that contains the row & column location of the target cell.
Here's the relevant part of my code:
Dim ImpactCells(15) As String
'Specify Form cell locations for specific programs
ImpactCells(0) = "4,2" 'Program 1
ImpactCells(1) = "5,2" 'Program 2
ImpactCells(2) = "6,2" 'Program 3
ImpactCells(3) = "4,4" 'Program 4
ImpactCells(4) = "5,4" 'Program 5
ImpactCells(5) = "6,4" 'Program 6
ImpactCells(6) = "7,2" 'Program 7
ImpactCells(7) = "10,2" 'Program 8
ImpactCells(8) = "11,2" 'Program 9
ImpactCells(9) = "12,2" 'Program 10
ImpactCells(10) = "13,2" 'Program 11
ImpactCells(11) = "10,4" 'Program 12
ImpactCells(12) = "11,4" 'Program 13
ImpactCells(13) = "12,4" 'Program 14
ImpactCells(14) = "13,4" 'Program 15
For i = 0 To 14 'Count of Programs Array
If Programs(i) <> "" Then 'If array element is not blank
Set cc = .SelectContentControlsByTag("Program" & i + 1).Item(1) 'Select the Content Control with the Program(array index) tag
cc.Checked = True 'Check it
End If
If ImpactCount(i) <> "" Then
'Code to populate cells here
.Tables(9).Cell(ImpactCells(i)).Range.Text = Me.Controls("txtImpact" & i + 1).Text
End If
Next
The line thats causing an error is:
.Tables(9).Cell(ImpactCells(i)).Range.Text = Me.Controls("txtImpact" & i + 1).Text
It says: Compile Error: Argument not optional and highlights the word cell. The code works when I put specific cell locations instead of ImpactCells(i).
Any help would be appreciated. Suggestions for a more efficient way of doing this would also be great, keeping in mind that I can't modify the way the Word table is laid out.
Cell requires a row and a column argument (both numeric). You're passing a single String argument.
You could try something like this:
Dim arr
'...
'...
If ImpactCount(i) <> "" Then
'Code to populate cells here
arr = split(ImpactCells(i),",") 'convert to array
.Tables(9).Cell(arr(0), arr(1)).Range.Text = _
Me.Controls("txtImpact" & i + 1).Text
End If

Extracting unique values from row in Excel

I need to summarize unique values from a row into a column that's in the same row. My goal is in the second row of the attached image where T:Z contains the data and AA:AC contains the summary (I typed the values in for the demo). The first row is what is currently occurring where I tried using a nested if function for values greater than zero, but I also tried using an index match function to no avail. The issue is I either receive duplicates in AA:AC or not all values are included.
Currently using Excel 2016
So if I understand you correctly, you are going to have a sheet of rows of data. You want to look in the columns T:Z and then generate a list of unique values (non-zero) in the columns AA:AC. I assume that you know you will never have more than 3 unique values, but I can't be sure that this wasn't just an omission.
Either way, the below code should work:
Sub Find_Uniques()
Dim X As Integer, Y As Integer, Z As Integer
Dim Temp_Strings() As String
For X = 1 to 10000 'This assumes you don't have more than 10,000 rows of data
ReDim Temp_Strings(1 to 5) As String
For Y = 20 to 26
If Range(Cells(X,Y).Address).Value <> "" And Range(Cells(X,Y).Address).Value <> 0 Then
For Z = 1 to 5
If Temp_Strings(Z) = "" Then
Temp_Strings(Z) = Range(Cells(X,Y).Address).Value
Exit For
End If
If Temp_Strings(Z) = Range(Cells(X,Y).Address).Value Then Exit For
Next Z
End If
Next Y
For Z = 1 to 5
If Temp_Strings(Z) <> "" Then Range(Cells(X,Z+26).Address)).Value = Temp_String(Z)
Next Z
Next X
End Sub
Thank you all for your help. Instead of extracting the data from the row, I wrote a macro that changed the zeros to blanks, deleted the blank cells, and shifted them to the left. After that it was easy to cut the range and paste it into the old data set to be analyzed.
Sub clean_data()
Sheets("Reason data").Range("H:Z").Replace 0, ""
Call delete_blanks
End Sub
Sub delete_blanks()
Sheets("Reason data").Range("H:Z").SpecialCells(xlCellTypeBlanks).Delete (xlToLeft)
Call move_data
End Sub
Sub move_data()
'Copies reason data and pastes it into data worksheet
Sheets("Reason data").Range("A3:K3", Sheets("Reason data").Range("A3:F3").End(xlDown)).Cut _
Sheets("Data").Range("A1").End(xlDown).Offset(1)
End Sub

Find average of a specific number of rows/columns in VB.Net Datatable and store to array

I am trying to program a noise reduction algorithm that works with a set of datapoints in a VB.NET DataTable after being helped with my other question. Basically, I want to take two integers, a coordinate value (yCoord for example) and a threshold smoothing value (NoiseThresh), and take the average of the values in the range of (yCoord - NoiseThresh, yCoord + NoiseThresh) and store that number into an array. I'd repeat that process for each column (in this example) and end up with a one-dimensional array of average values. My questions are:
1) Did anything I just say make any sense ;), and
2) Can anyone help me with the code? I've got very little experience working with databases.
Thanks!
An example of what I'm trying to do:
//My data (pretend it's a database)
1 4 4 9 2 //yCoord would equal 5
6 3 8 12 3 //yCoord = 4
8 3 -2 2 0 //yCoord = 3
9 17 3 7 5 //yCoord = 2
4 1 0 9 7 //yCoord = 1
//In this example, my yCoord will equal 3 and NoiseThresh = 1
//For the first column
Array(column1) = //average of the set of numbers centered at yCoord = 3 _
//(in this case 8) and the NoiseThresh=1 number on either side (here 6 & 9)
//For the second column
Array(column2) = //average of the numbers 3,3,17 for example
//etc., etc.,
This would be performed on a large data set (typical numbers would be yCoord=500, NoiseThresh = 50, Array length = 1092) so there is no possibility of manually entering the numbers.
I hope this helps clarify my question!
P.S.: yes, I know that // isn't a VB.NET comment.
I must admit that i've yet not understood the range part (NoiseThresh etc.), but this is a start:
Dim averages = (From col In tbl.Columns.Cast(Of DataColumn)()
Select tbl.AsEnumerable().
Average(Function(r) r.Field(Of Int32)(col.ColumnName))).
ToArray()
It calculates every average of each column in the DataTable and creates a Double() from the result (average can result in decimal places even if used on integers).
Edit: With your example i've now understood the range part. So basically yCord is the row-index(+1) and noiseThreas is the row-range (+/- n rows).
Then this gives you the correct result(made some code comments):
Dim yCord = 2 ' the row index(-1 since indices are 0-based) '
Dim noiseThresh = 1 ' +/- row '
' reverse all rows since your sample begins with index=5 and ends with index=1 '
Dim AVGs As Double() = (
From colIndex In Enumerable.Range(0, tbl.Columns.Count)
Select tbl.AsEnumerable().Reverse().
Where(Function(r, index) index >= yCord - noiseThresh _
AndAlso index <= yCord + noiseThresh).
Average(Function(r) r.Field(Of Int32)(colIndex))).ToArray()
The most important part of this this LINQ query is the Where. It applies your range on the IEnumerable(of DataRow). Then i'm calculating the average of these rows for every column. The last step is materializing the query to a Double().
Result:
(0) 7.666666666666667 Double => (6+8+9)/3
(1) 7.666666666666667 Double => (3+3+17)/3
(2) 3.0 Double => (8-2+3)/3
(3) 7.0 Double => (12+2+7)/3
(4) 2.6666666666666665 Double => (3+0+5)/3
Edit2:
One last thing. I assume that to do the same for the other axis I just
switch x & y and row & column?
It's not that simple. But have a look yourself:
Dim noiseThresh = 1 ' +/- column '
Dim xCord = 2 ' the column index(-1 since indices are 0-based) '
' assuming that your x-cords now start with index=0 and ends with tbl.Column.Count-1 '
Dim AVGs As Double() = (
From rowIndex In Enumerable.Range(0, tbl.Rows.Count)
Select tbl.Columns.Cast(Of DataColumn)().
Where(Function(c, colIndex) colIndex >= xCord - noiseThresh _
AndAlso colIndex <= xCord + noiseThresh).
Average(Function(c) tbl.Rows(rowIndex).Field(Of Int32)(c.Ordinal))).ToArray()
Result:
(0) 5.666666666666667 Double => (4+4+9)/3
(1) 7.666666666666667 Double => (3+8+12)/3
(2) 1.0 Double => (3-2+2)/3
(3) 9.0 Double => (17+3+7)/3
(4) 3.3333333333333335 Double => (1+0+9)/3

Resources