How to modify Totals row in Access 2013 - database

I'm trying to modify a total query so that if the amount of the sum surpasses 1000 for example it changes the value in 2 fields. for example, 1000 grams change to 1 kilogram, and vice versa.
For example, if I have 20 items in grams, and the total of the sum of those 20 items is 1200 grams, how do I make it so that it automatically changes it to 1.2 kilograms. How do I make it detect that its over 1000 to convert it from grams to kilograms.

How about
Function presentFormattedWeight(Weight as Long) as String
Dim KgWeight as Long
Dim GramWeight as Long
KgWeight =0
if(Weight mod 1000)>0 then
KgWeight = Weight\1000
GramWeight = Weight mod 1000
else
GramWeight = Weight
end if
if KgWeight >0 then
presentFormattedWeight = KgWeight & "." & GramWeight & "Kg"
else
presentFormattedWeight = GramWeight & "grams"
end if
End Function

Related

VBA create loop for column B based on value in column A

I have a code that does what I need. The problem is I have to do the range select manually I'd like to create a conditional loop.
Here's my code that I used so far
Sub Worksheet_functions()
Dim Sumtotal As Long
Sumtotal = WorksheetFunction.Sum(Selection)
Range("e2").Value = Sumtotal
Range("h2").Value = Range("e2") + Range("h2")
End Sub
This is what my data looks like
Price Volume E H
10 100
10 50
10 80
9 100
9 50
8 100
8 100
10 50
10 250
At the moment I'm manually selection the volume column from the top down based on the value in price column.
The conditions are
If The prices are the same continue selecting them until they are not
If the price goes down then those selected cells should be summed in e4 and added to h4
If the price goes up then those selected cells should be summed in e2 and added to h4
For my example this would look like:
( H2: 100+50+80 +50+250 = 530 )
( H4: 100+50 +100+100 = 350 )
Price Volume
( 10 100
100+50+80 < ( 10 50
( 10 80
Above volume to H2
(9 100
100+50 < (9 50
Above volume to H4 ( because 10>9)
(8 100
100+100 < (8 100
Above volume to H4 ( because 9>8)
(10 50
50+250 < (10 250
Above volume to H2 ( because 8<10)
Any suggestions on
How do I use the conditions to make it loop?
How do write a code that takes in consideration the last price?
Here's a way to get what you want.
It is much difficult to create loop and Nested If's to do this.
I let Excel do the job and used Formula instead.
Let say your data is in A1:B10.
In E2 type this in formula bar.
=IF(A2=A3,IF(ISNUMBER(A1),IF(A1<A2,1,IF(A1=A2,E1,0)),1),IF(ISNUMBER(A1),IF(A1<A2,1,IF(A1=A2,E1,0)),1))
Copy the formula all the way down until E10 or up to where you have data.
In H2, type this in formula bar:
=SUMIF(E:E,1,B:B)
Similarly in H4, type this in formula bar:
=SUMIF(E:E,0,B:B)
However, you want code in VBA which is below also using above formula:
Dim ws as Worksheet, lrow as long
Set ws = Thisworkbook.Sheets("Sheet1")'assuming your data is in Sheet1
With ws
lrow = .Range("A" & .Rows.Count).End(xlUp).Row
.Range("E2:E" & lrow).Formula = "=IF(A2=A3,IF(ISNUMBER(A1),IF(A1<A2,1,IF(A1=A2,E1,0)),1),IF(ISNUMBER(A1),IF(A1<A2,1,IF(A1=A2,E1,0)),1))"
.Range("E2:E" & lrow).Value = .Range("E2:E" & lrow).Value
.Range("H2").Formula = "=SUMIF(E:E,1,B:B)"
.Range("H2").Value = .Range("H2").Value
.Range("H4").Formula = "=SUMIF(E:E,0,B:B)"
.Range("H4").Value = .Range("H4").Value
End With
End Sub
Kinda late, but I hope this is what you want.

Truly drawing cards at random, and not just a random group? visual basic 2010

I realized a flaw on my coding for picking cards from my structure group arrays this morning for a tabletop card game I'm converting to computer.
Currently the code is set up to randomly pick an array of a specific card, but if quantity of cards in the group is < 1, then the group is skipped. For my deck this isn't being truly random because each card has its own quantity. Some cards have 10 cards, others 6, most 4. How can I code it to where it looks at all these quantity numbers as a whole and picks a random card out of these numbers.
If GameSize >= 3 Then
For StartHands = 10 To 14
Number = (DeckGroup(Rnd.Next(0, DeckGroup.Count)).ID)
'Cardslots Player3
If CardTypeArray(StartHands) = "" Then
If DeckGroup(Number).QuantityInteger > 0 Then
DeckGroup(Number).QuantityInteger -= 1
Player1HandGroup(Number).QuantityInteger3 += 1
CardTypeArray(StartHands) = Player1HandGroup(Number).CardType
Me.NumberArray(StartHands) = Number
Else
'Recall Procedure if Generated Random Number is not allowed
'due to QuantityInteger <= 0
Call StartButton_Click(sender, e)
End If
End If
Next StartHands
End If
when playing a card, and drawing a new card, I use this coding scheme, to prevent stackoverflow, but is virtual the same.
Dim temp As IEnumerable(Of LunchMoneyGame.LunchMoneyMainForm.Group) = From r In DeckGroup Where r.QuantityInteger > 0 Select r
If temp IsNot Nothing AndAlso temp.count > 0 Then
Number = (temp(Rnd.Next(0, temp.Count)).ID)
DeckGroup(Number).QuantityInteger -= 1
'Select the Player depending value of T
Select Case T
Case 0
Player1HandGroup(Number).QuantityInteger += 1
Case 1
Player1HandGroup(Number).QuantityInteger2 += 1
Case 2
Player1HandGroup(Number).QuantityInteger3 += 1
Case 3
Player1HandGroup(Number).QuantityInteger4 += 1
Case 4
Player1HandGroup(Number).QuantityInteger5 += 1
End Select
Edit:
Improved question:
How can I weight the probably of drawing a card based on how many of a particular card are left in the decks quantity integer for each card?
The idea of my solution is to generate a random number over the total number of availables cards in all deck groups. Finally we find the deck group this number targets within a loop:
Dim totalNumerOfCards As Integer = DeckGroup.Sum(Function(d) d.QuantityInteger)
Dim Number As Integer = Rnd.Next(totalNumerOfCards)
Dim numCards As Integer = 0
Dim groupIndex As Integer = 0
Dim cardIndex As Integer = 0
Dim i As Integer = 0
While i < DeckGroup.Length AndAlso numCards <= Number
groupIndex = i
cardIndex = Number - numCards
numCards += DeckGroup(i).QuantityInteger
i += 1
End While
Console.WriteLine("Your card is in DeckGroup({0}), card index {1}",
groupIndex, cardIndex);

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

Loop in Excel VBA

I have a logic in place, but no idea as to how to execute/code it in Excel. The logic is below:
At office, I need to find out the value of many old articles based on their purchase value and age. I don't want to use VDB or other inbuilt functions.
In my spreadsheet:
A1 = "Table" (Name of the article)
B1 = "01/01/2005" (Date of purchase in MM/DD/YYYY format)
C1 = "1000" (Purchase value)
D1 = "=DATEDIF(B1,TODAY(),"Y")" (Gives the age of article in years)
E1 = "20" (Percentage depreciation for first year, which varies based on article)
F1 = "=C1*10%" '(Depreciated value should not be less than 10% of purchase value)
Now, in G1 I want to calculate the depreciation value of article "A1" with purchase value "C1" for "D1" number of years, # flat "E1"% for first year and 10% for subsequent years.
H1 = "=C1-G1" (Value of the article after depreciation)
I1 = "=IF(H1<=F1,F1,H1)"
Please help me with a macro or formula to loop and find out the value of G1.
Also, I want to apply this to "n" number of rows since there are "n" number of articles.
EDIT
#assylias Thanks for enlightening me about SO policy, putting me to work for myself to find the answer.
After some 30 min of googling followed by trial and error, I successfully wrote a macro to do what I wanted. Here it goes:
Sub DepVal()
'
' DepVal Macro
' Macro by Prashanth JC
'
' Keyboard Shortcut: Ctrl+d
'
fYear = 0
dVal = 0
tYear = ActiveCell.Offset(0, -3)
purVal = ActiveCell.Offset(0, -4)
depFirst = ActiveCell.Offset(0, -2)
depOther = 10
If tYear >= 1 Then
Do
If fYear = 0 Then
dVal = purVal - (purVal * depFirst) / 100
Else
dVal = dVal - (dVal * depOther) / 100
End If
fYear = fYear + 1
Loop Until fYear = tYear
ActiveCell.Value = dVal
Else
ActiveCell.Value = purVal
End If
End Sub
Finally, I formatted the G1 cell to a Number with Zero decimal place. Everything works perfect now!
Thanks again, SO and assylias!
You don't need a macro, it's simple math.
Assuming that your percentage (in E1) is stored as .2 (for 20%), not actually 20, this formula would work:
=MAX(F1,C1*(1-E1)-(C1*0.1*(D1-1)))

How to apply the formula on a summary field

I am developing an inventory system and I have developed the following function to convert between cartons and pieces.
Public Function convertQTY(ByVal units_case As Integer, ByVal quantity As QTY) As QTY
While quantity.pieces < 0 And quantity.cartons > 0
If quantity.pieces < 0 And quantity.cartons > 0 Then
quantity.pieces = units_case + quantity.pieces
quantity.cartons -= 1
End If
End While
If quantity.pieces >= units_case Then
quantity.cartons = quantity.cartons + (quantity.pieces \ units_case)
quantity.pieces = quantity.pieces Mod units_case
End If
Return quantity
End Function
For example if units/pieces per carton is 144 then the above code converts the pieces into cartons if the number exceeds 144 and if the pieces are less than 0 then the above code subtracts 1 from carton and adds units per carton into the number of pieces. So that the pieces never exceed total number of pieces in a carton and they are never shown to be less than 0.
I want the same effect in summary field in my crystal report. For showing sum of cartons and pieces at the end of each group. How can i achieve this?
By creating formulas for the number of cartons and remaining pieces, like so:
Number Of Cartons:
Sum ({MyTable.Pieces})\144
Remaining Pieces:
Sum ({MyTable.Pieces}) mod 144

Resources