EXCEL - Convert TON to KG incorrect - excel-formula

I have Excel 365 on MAC.
I want to convert "weight unit" in another "weight unit".
=CONVERT(number; from_unit; to_unit)
Why is 1 ton = 907kg ? This should be 1000kg
Amount Unit Amount Unit
1 ton => 907,18474 kg
1 kg => 1000 g
1 g => 1000 mg
What is the correct way to convert?
Thanks,
Aykut

In Britannica encyclopedia defined ton:
ton, a unit of weight in the avoirdupois system equal to 2,000 pounds (907.18 kg) in the United States (the short ton) and 2,240 pounds (1,016.05 kg) in Britain (the long ton). The metric ton used in most other countries is 1,000 kg, equivalent to 2,204.6 pounds avoirdupois.
Microsoft Excel just support "ton" and "uk_ton"

Excel function did not work for unit conversion from tons (metric) to other weight units.
Excel out of the box function:
=Convert(value; from_unit; to_unit)
I would like to share my (workaround) solution with the same attributes as Excel:
=myConvert(value; from_unit; to_unit)
Public Function myConvert(value As Variant, f_unit As String, to_unit As String) As Variant
Dim conversion As String
Dim position As Integer
Dim unit_array As Variant
unit_array = Array( _
"mg_mg", "mg_g", "mg_kg", "mg_t", _
"g_mg", "g_g", "g_kg", "g_t", _
"kg_mg", "kg_g", "kg_kg", "kg_t", _
"t_mg", "t_g", "t_kg", "t_t" _
)
Dim formula_array As Variant
formula_array = Array( _
"", "/ 1000", "/ 1000000", "/ 1000000000", _
"* 1000", "", "/ 1000", "/ 1000000", _
"* 1000000", "* 1000", "", " / 1000", _
"* 1000000000", "* 1000000", "* 1000", "" _
)
conversion = f_unit & "_" & to_unit
position = array_pos(unit_array, conversion)
value = Replace(value, ",", ".")
If (IsNumeric(value) = False) Then
myConvert = "not a number"
Exit Function
ElseIf (position < 0) Then
myConvert = "unknown unit"
Exit Function
End If
myConvert = Evaluate(value & " " & formula_array(position))
End Function
Function array_pos(my_array, my_value)
array_pos = -1
For ii = LBound(my_array) To UBound(my_array)
If my_array(ii) = my_value Then 'value found
array_pos = ii
Exit For
End If
Next
End Function
Here is the test result:
1 t = 1 t
1 t = 1000 kg
1 t = 1000000 g
1 t = 1000000000 mg
1 kg = 0,001 t
1 g = 0,000001 t
1 mg = 0,000000001 t
1 t = unknown unit x because x as unit is unknown
y t = not a number kg because y is not a number

Related

VBA convert time on Number

I need to convert my time to Number. i need it because letter i'm going to divide this dates by yourself to calculate % (agent productive time ).
I tried something like this
'cells(2,3) = 22:12:2
cells(2,3) / (60*60*1000)
Thanks in advance
You can do like this:
a = "78:19:41"
b = "74:23:58"
ta = (Split(a, ":")(0) / 24) + TimeValue("00:" & Split(a, ":", 2)(1))
tb = (Split(b, ":")(0) / 24) + TimeValue("00:" & Split(b, ":", 2)(1))
p = tb / ta * 100
p -> 94.9844138434859

Type Mismatch Error And Bisection inside Integration inside iterative loop

I am trying to convert a Mathcad calculation to excel spreadsheet. I am trying to find a variable called kw. I am getting type mismatch error in the line:
INTEG = INTEG + ...
Would someone know why I am getting this error ? I have already spent a lots of time on it but couldn't find the reason. As this work is really important to me, I would like to thank in advance any help/suggestion on it.#
Option Explicit
Dim wp As Double, alpha As Double, w As Double, gama As Double, d As Double
Dim kw As Double, n As Integer, sExp As String, g As Double
'Calculating kw
Sub CalculateKw()
Dim l As Integer
alpha = ThisWorkbook.Sheets("Current-Wave Calculation").Range("H49").Value
gama = ThisWorkbook.Sheets("Current-Wave Calculation").Range("H34").Value
d = ThisWorkbook.Sheets("Environmental Data Input").Range("H4").Value
wp = ThisWorkbook.Sheets("Current-Wave Calculation").Range("H47").Value
kw = 100
For l = 1 To 99
If Err.Number = 0 Then
kw = INTEG(0, kw, 5000)
Else
kw = kw - 1
End If
Next l
ThisWorkbook.Sheets("Sheet1").Range("B1").Value = kw
End Sub
'DEFINITE INTEGRAL from 0 to kw*wp to solve JONSWAP Equation
Function INTEG(n, kw, lBit As Long)
Dim SpectralWidthParameter As Double, dMin As Double, dMax As Double
Dim dW As Double, lW As Long, AAA As String
g = 9.80665
alpha = ThisWorkbook.Sheets("Current-Wave Calculation").Range("H49").Value
gama = ThisWorkbook.Sheets("Current-Wave Calculation").Range("H34").Value
d = ThisWorkbook.Sheets("Environmental Data Input").Range("H4").Value
wp = ThisWorkbook.Sheets("Current-Wave Calculation").Range("H47").Value
dMin = 0
dMax = kw * wp
If w <= wp Then
SpectralWidthParameter = 0.07
Else
SpectralWidthParameter = 0.09
End If
sExp = "(w ^ n) * (((w / _
(Application.WorksheetFunction.Sinh(WaveNumber(0,20,w,d) * d))) ^ 2)*
(alpha * (g ^ 2) * (w ^ (-5)) * (EXP((-5 / 4) * ((w / wp) ^ (-4)))) *
(gama ^ (EXP(-0.5 * (((w - wp) / (SpectralWidthParameter * wp)) ^ 2))))))"
sExp = Replace(sExp, "EXP", "AAA")
dW = (dMax - dMin) / lBit
For lW = 1 To lBit
*INTEG = INTEG + Evaluate(Replace(Replace(sExp, "w", dMin), "AAA", _
"EXP")) * dW + 0.5 * dW * Abs(Evaluate(Replace(Replace(sExp, "w", dMin _
+dW), "AAA", "EXP")) - Evaluate(Replace(Replace(sExp, "w", dMin), _
"AAA", "EXP")))*
dMin = dMin + dW
Next lW
End Function
'BISECTION METHOD TO CALCULATE Wave number k
Function WaveNumber(a, b, w, d)
Dim klow As Double, khigh As Double, kmid As Double, i As Integer
Dim a As Integer, b As Integer
klow = a
khigh = b
kmid = (klow + khigh) / 2
For i = 1 To 100
If SolveFunction(klow, w, d) * SolveFunction(kmid, w, d) < 0 Then
khigh = kmid
kmid = (klow + khigh) / 2
Else
klow = kmid
kmid = (klow + khigh) / 2
End If
Next i
WaveNumber = kmid
End Function
'HELPER FUNCTION(Wave Dispersion Equation)FOR BISECTION METHOD
Function SolveFunction(k, w, d)
SolveFunction = k * Application.WorksheetFunction.Tanh(k * d) - (w ^ 2) _
/ 9.80665
End Function
INTEG = INTEG + Evaluate(....)
"Type mismatch" because your Evaluate expression returned an error. Adding a number to an error variant generates that runtime error.
Basically you shouldn't insert Application.WorksheetFunction.Sinh(...) in the evaluated expression, but just Sinh(...).
Moreover I think that you can re-write your code without using Evaluate, this will make debugging your code easier.

VBScript string replace with range instead of string?

Replace() already exists, but that function takes strings as parameters. I need range.
In my string there are two "strings" that are 10 characters long.
Greger with 6 chars and 4 spaces and the other string with 10 characters.
"Greger AASSDDFFGG"
I want to replace "Greger " with "googlioa "
What i'm looking for is basically this:
Replace(MyString,1,10) = "googlioa "
Is there any way to achieve this?
If they're always going to be 10 chars, just pad the names.
strNameFind = "Greger"
strNameReplace = "googlioa"
' Pad the names...
strNameFind = Left(strNameFind & Space(10), 10)
strNameReplace = Left(strNameReplace & Space(10), 10)
MyString = Replace(MyString, strNameFind, strNameReplace)
Alternatively, if you don't want to determine the existing name, just pad your new name appropriately and add the remainder of your string:
' Pad the new name to fit in a 10-char column...
strNameReplace = "googlioa"
strNameReplace = Left(strNameReplace & Space(10), 10)
' Update the record...
MyString = strNameReplace & Mid(MyString, 11)
If you want to replace strictly by position, use concatenation of Left(), new, and Mid(). To get you started:
>> Function replByPos(s, f, l, n)
>> replByPos = Left(s, f-1) & n & Mid(s, f + l - 1)
>> End Function
>> s = "Greger AASSDDFFGG"
>> r = replByPos(s, 1, 10, "googlioa ")
>> WScript.Echo s
>> WScript.Echo r
>>
Greger AASSDDFFGG
googlioa AASSDDFFGG
>>
Further enhancements:
safety: f(rom) - 1 is risky - should be checked
padding of new string wrt l(ength)
perhaps you want to search (Instr()) for old ("Greger ") before the concatenation
On second thought (and stealing Bond's padding):
Maybe I should have interpeted the 10 as a to/till/upto value instead of a length/width specification. So see whether
Option Explicit
Function replByPos(src, from, till, ns)
Dim w : w = till - from
replByPos = Left(src, from - 1) & Left(ns & Space(w), w) & Mid(src, till)
End Function
Dim s : s = "Greger AASSDDFFGG"
Dim ns : ns = "googlioa"
WScript.Echo s
WScript.Echo replByPos(s, 1, 10, ns)
s = "Whatever Greger AASSDDFFGG"
ns = "googlioa"
Dim p : p = Instr(s, "Greger")
WScript.Echo s
WScript.Echo replByPos(s, p, p + 10, ns)
output:
cscript 22811896.vbs
Greger AASSDDFFGG
googlioa AASSDDFFGG
Whatever Greger AASSDDFFGG
Whatever googlioa AASSDDFFGG
matches your specs better.

Who owes who money algorithm in excel spreadsheet

I have a group of people who have different expenses during a period. Everybody has a balance after this period. It looks like this in excel:
Person A: 6
Person B: 10
Person C: -7,5
Person D: -8,5
After this period a settlement will take place. I currently do this by manually. This results in:
Person C pays 6 to person A.
Person C pays 1,5 to person B.
Person D pays 8,5 to person B.
Person A gets 6 from person C.
Person B gets 1,5 form person C.
Peron B gets 8,5 from person D.
(There are multiple solutions possible when more persons are involved.)
The problem is that I have to apply this procedure for a big group of people. So my question is: 'How to apply this 'who owes who'-procedure by using an excel spreadsheet algorithm or macro?'.
I made a excel version too but its in Open office. can you download that? The following macro might work on its own. If it does not should be something small. it works fine in OOO and is saved as a Excel 97/2000 workbook document.
'this might not be needed in Microsoft Excel, comment it out
Option VBASupport 1 'OWES
Option Explicit
'Cells(row, col),
Private Sub cmd1_Click()
'data is same sheet, from row 4, column 4
'row 4 has names in columns, so 4,4 has name 1, 4,5 has name 2
'row 5 has amounts spent like 6, -10
'output is in columns 3 and 5
dim i
dim j,s as String, sum1
s=""
'get number of cells used in row 4 and check if corresponding row 6 column has a number value too
i = 4
sum1=0
do while(cells(4,i).Value <> "" and i < 500)
j = CDbl(cells(5,i).Value)
sum1 = sum1 + j
if j <> cells(5,i).Value then
MsgBox "Col " & i & " not a number?"
End
end if
i=i+1
loop
if i > 499 then
Msgbox "too many cols"
End
end if
If sum1 > 0.3 or sum1 < -0.3 then
Msgbox "Sum is not near 0 :" & sum1
End
End if
Dim colCnt as Integer
colCnt = i - 4
cells (7,1).Value = "Col count = " & colCnt
Dim spent(colCnt) as Double
Dim owes1(colCnt ) as String
Dim owes2(colCnt ) as String
for i= 4 to colCnt + 3
spent(i - 3) = CDbl(cells(5,i).Value)
Next
Dim cnt,lastNeg, abs1,maxPay ' safety var for never ending loops, only if data bad like many cols and more than .1 diffs
lastNeg = 4
dim lastPay1
lastPay1 = 10
dim ii,jj,c1,c2,toPay
toPay = 0
On Local Error Goto errh
for i= 4 to colCnt + 3
cnt = 0
ii = i - 3
c1 = spent(ii)
'Cells(6,i) = "ok "
if spent(ii) > 0.1 and cnt < colCnt Then '//has to take
cnt = cnt + 1
for j = lastNeg to colCnt + 3 ' ; j < people.length && spent(ii) > 0.1; j++)
jj = j - 3
's = s & Me.Cells(ii,j) & " "
if spent(ii) > 0.1 then
if spent(jj) < -0.1 Then ' //has to give and has balance to give
c1 = spent(ii)
c2 = spent(jj)
lastNeg = j
abs1 = spent(jj) * -1'//can use absolute fn
maxPay = abs1
if(maxPay > spent(ii)) Then
toPay = spent(ii)'
else
toPay = abs1
End if
spent(ii) = spent(ii) - toPay
spent(jj) = spent(jj) + toPay
Cells(lastPay1, 3).Value = Cells(4 , j) & " pays " & toPay & " to " & Cells(4 , i )
Cells(lastPay1, 5).Value = Cells(4 , i) & " gets " & toPay & " from " & Cells(4 , j)
lastPay1 = lastPay1 + 1
End if
End if
Next
End if
Next
Msgbox "Done"
err.Clear
if err.Number <> 0 Then
errH:
dim yy
yy = msgBox("err " & err.Number & " " & err.Description & " Continue", 2)
if yy = vbYes Then
Resume Next
End IF
End IF
End Sub
Book at http://sel2in.com/prjs/vba/profile (owes)
Can see http://www.excel-vba.com/ , http://office.microsoft.com/en-in/training/get-in-the-loop-with-excel-macros-RZ001150634.aspx the help in excel was useful too (f1 inside macro editor, can select a keyword or type and get context sensitive help by pressing f1)
How important is the pairing of who owes what to who? The reason I ask - it's simple to figure out the total cost per person and then determine who owes money and who needs a refund. If one person can be the "banker", he can collect all the money due and disburse all the refunds.
Much simpler question, if you have somebody willing to be the banker.
Trying to pair everything up will quite possibly not result in an exact answer, or may require one or more people making payments to more than one person - as well as one or more people trying to collect from more than one other person.
See http://sel2in.com/pages/prog/html/owes.html
Javascript fn
<form>
Paste tab seperated list of people on first line, Second line has blanace - positive means they spent more than others, negative means other spent on them (they owe)
<br>
<textarea id=t1 rows=3 cols=70></textarea>
</form>
<button onclick=calcOwes() >Calc owes</button>
<br>
<b>Result:</b>
<div id=result>Will appear here if data is good</div>
<br>
<b>Parsed data for debug:</b>
<div id=data1>Will appear here if data is good</div>
<br>
<hr>
<script>
function calcOwes(){
/**
2013 Tushar Kapila
If Person A: 6
Person B: 10
Person C: -7,5
Person D: -8,5
Then Person C pays 6 to person A.
Person C pays 1,5 to person B.
Person D pays 8,5 to person B.
*/
s = document.getElementById("t1").value
var line = s.split("\n")
//v = confirm("Your Data looks okay?:\n" + s)
//if(!v){ return;}
if(s.length < 2 || s.indexOf("\n") < 0){
alert("No line sep ")
return
}
people = line[0].split("\t")
spent = line[1].split("\t")
spent2 = line[1].split("\t")
if(spent.length < 2){
alert("Bad data, no spent data " + spent.length + "; 0 " + spent[0] + "; 1 " + + spent[1])
return
}
if(people.length != spent.length){
alert("People and amounts do not tally. make sure no tabs inside names, spaces are okay")
return
}
sum = 0;
data1o = document.getElementById("data1")
data1o.innerHTML = "";
for(i = 0;i < people.length; i++){
spent[i] = spent[i].trim()
spent[i] = parseFloat(spent[i])
sum += spent[i]
s = (1 + i) + " \"" + people[i] + "\" :" + spent[i] + ";<br>"
data1o.innerHTML += s;
}
if(sum > 0.2 || sum < -0.2){
v = confirm("Sum (" + sum + ")is not zero continue?")
if(!v){return;}
}
lastNeg = 0;
payDetails = new Array();
getDetails = new Array();
lastPay = 0;
for(i = 0;i < people.length; i++){
cnt = 0;
if(spent[i] > 0.1 && cnt < people.length){//has to take
cnt++
for(j = lastNeg; j < people.length && spent[i] > 0.1; j++){
if(spent[j] < -0.1){//has to give and has balance to give
lastNeg = j;
abs1 = spent[j] * -1;//can use absolute fn
maxPay = abs1
if(maxPay > spent[i]){
toPay = spent[i];
}else{
toPay = abs1
}
spent[i] -= toPay
spent[j] += toPay
payDetails[lastPay] = people[j] + " pays " + toPay + " to " + people[i]
getDetails[lastPay] = people[i] + " gets " + toPay + " from " + people[j]
lastPay++;
}
}
}
}
s = ""
s2 = ""
for(i = 0;i < lastPay; i++){
s = s + payDetails[i] + "<br>"
s2 = s2 + getDetails[i] + "<br>"
}
document.getElementById("result").innerHTML = s + "<br>" + s2
}
</script>
<br>Sample input 1 (tabs there?)
<br><pre>
a b c d
6 10 -7.5 -8.5
</pre>
<br>Sample input 2
<pre>
Anna Dan Bobby Scareface Colly Doc Egg face
-6 10 -7.3 -8.33 11.67
</pre>

Convert Number to Corresponding Excel Column [duplicate]

This question already has answers here:
How to convert a column number (e.g. 127) into an Excel column (e.g. AA)
(60 answers)
Closed 8 years ago.
I need some help in doing a logic that would convert a numeric value to corresponding MS Excel header value.
For example:
1 = "A"
2 = "B"
3 = "C"
4 = "D"
5 = "E"
.........
25 = "Y"
26 = "Z"
27 = "AA"
28 = "AB"
29 = "AC"
30 = "AD"
.........
Would appreciate some .NET codes (C# or VB) for this. Thanks.
Here's some VBA (with test code) I strung together in Excel which does the trick. Unless VB.NET has changed drastically, it should work okay. Even if it has, you should be able to translate the idea into workable code.
' num2col - translate Excel column number (1-n) into column string ("A"-"ZZ"). '
Function num2col(num As Integer) As String
' Subtract one to make modulo/divide cleaner. '
num = num - 1
' Select return value based on invalid/one-char/two-char input. '
If num < 0 Or num >= 27 * 26 Then
' Return special sentinel value if out of range. '
num2col = "-"
Else
' Single char, just get the letter. '
If num < 26 Then
num2col = Chr(num + 65)
Else
' Double char, get letters based on integer divide and modulus. '
num2col = Chr(num \ 26 + 64) + Chr(num Mod 26 + 65)
End If
End If
End Function
' Test code in Excel VBA. '
Sub main()
MsgBox ("- should be " & num2col(0))
MsgBox ("A should be " & num2col(1))
MsgBox ("B should be " & num2col(2))
MsgBox ("Z should be " & num2col(26))
MsgBox ("AA should be " & num2col(27))
MsgBox ("AB should be " & num2col(28))
MsgBox ("AY should be " & num2col(51))
MsgBox ("AZ should be " & num2col(52))
MsgBox ("BA should be " & num2col(53))
MsgBox ("ZY should be " & num2col(27 * 26 - 1))
MsgBox ("ZZ should be " & num2col(27 * 26))
MsgBox ("- should be " & num2col(27 * 26 + 1))
End Sub
public string ColumnNumberToLetter(int ColumnNumber)
{
if (ColumnNumber > 26)
{
return ((char) (Math.Floor(((double)ColumnNumber - 1) / 26) + 64)).ToString()
+ ((char) (((ColumnNumber - 1) % 26) + 65)).ToString();
}
return ((char)(ColumnNumber+64)).ToString();
}
Try this:
public static string ToExcelString(int number)
{
if (number > 25)
{
int secondaryCounter = 0;
while (number > 25)
{
secondaryCounter = secondaryCounter + 1;
number = number - 25;
}
return ToExcelChar(number) + ToExcelChar(secondaryCounter);
}
else
{
return ToExcelChar(number)
}
}
private const string alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
private static string ToExcelChar(int number)
{
if (number > 25 || number < 0)
{
throw new InvalidArgumentException("the number passed in (" + number + ") must be between the range 0-25");
}
return alphabet[number];
}
Use a number base conversion routine. You want to convert from base 10 to base 26. Add each digit to 'A'
As in: http://www.vbforums.com/showthread.php?t=271359
Just Use the activecell.address then manuipulate the string based on where the $ is to what you need.

Resources