Question

I am trying to make a certain string with Digits change form, so that it looks like below.

Modified to show with Digits instead of X.

So let´s set, i get a number, like this.

234.123123123

I need to change how it appears, for 3 digits before a Dot, it would need to become.

0.234123123123

And let´s say it´s 2.23123123123, that would become, 0.0023123123123

Now i will try to explain the Formula, bare with my English.

The formula needs to change the position of the Dot ".". You can see that it changes place, But you can also see that i am adding 0s.

That is important, the 0s needs to be added IF the dot get´s to the far left (the beginning of the string).

So how much must the Dot move?

The Dot must Always move 3 steps to the left.

And if it hit´s the wall (the start of the string) you need to add 0s, and then one 0s before the dot.

So if the number is, 2.222222 I will first have to move the dot to the left, let´s show step by step.

Step 1:
.2222222

Step 2:
.02222222

Step 3:
0.02222222

It must Always be a 0 Before the Dot, it it ever hit the Start.

It sounds more complicated then it is, it´s just that i don't know how to explain it.

EDIT:

My attempt:

      TextPos = InStr(1, TextBox4.Value, ".") - 2
If (TextPos = 4) Then
     sLeft = Left(TextBox4.Value, Len(TextBox4.Value) - Len(TextBox4.Value) + 2)
      sRight = Right(TextBox4.Value, Len(TextBox4.Value) - 2)
      sFinal = (sLeft & "." & Replace(sRight, ".", ""))
      TextBox4.Value = Replace(sFinal, "-", "")
      End If
If (TextPos = 3) Then
      TextBox4.Value = "0." + Replace(TextBox4.Value, ".", "")
      End If
If (TextPos = 2) Then
      TextBox4.Value = "0.0" + Replace(TextBox4.Value, ".", "")
End If
If (TextPos = 1) Then
      TextBox4.Value = "0.00" + Replace(TextBox4.Value, ".", "")
End If
TextBox4.Value = Replace(TextBox4.Value, "-", "")

If i /1000 it, may work, but it seems like it will alter the number, leaving it to fail.

Original: 25.1521584671082

/1000 : 2.51521584671082E-02

As you can see, it doesn't work as expected.

It should become 0.0251521584671082E-02 (And of course i don't want " E- " to be there. So if it's possible to do this, but ONLY moving and not actually, dividing (i think excel is limited to how many numbers it can calculate with) then it will work.

Worth Noting, the numbers shown are actually less (shorter) then the real number for some reason, if i write it down to a text file, it becomes this:

2.51521584671082E-02251521584671082E-02

So as you can see, i probably hit a Wall in the calculation, so it changes to Characters (I know math uses those, but no idea what they mean, and they are useless for me anyway).

And i think it's because of them that it fails, not sure though.

EDIT:

Okay, by limiting to 15 decimals it will return the correct place, but i would like not to do this round about, should Excel really be limited to only 15 Decimals, or is it "Double,Float etc" that does this?

EDIT 2:

Tony's example provides this:

Original: 177.582010543847177582010543847
Tony's: 0.1775820110177582011
Round(15decimals): 0.1775820105438470177582010543847

Not really sure, but isn't it Incorrect, or perhaps i did something wrong?

If possible, i want ALL decimals and number to stay in place, as everything is already correct, it's just that they are in the wrong place.

/1000 solves this, but not in the best way, as it will recalculate instead of just moving. Normally i wouldn't care, the results are the same, but here it does matter as you can see.

I can however think of a solution, where i till look for the position of the Dot, then cut out the last decimals, divide the Result by 1000, then later add the last decimals, though that is more of a hack , not sure if it will actually work.

I conclude that this is Answered, it does what i want, and the limitations is in the Calculation itself, not the Solution. All Solutions work pretty much in the same way, but i chose Tony's as he was first to comment the solution in my question.

Many Thanks everyone!

Was it helpful?

Solution

You code sometimes fails because it does not handle every situation. You calculate TextPos so:

TextPos = InStr(1, TextBox4.Value, ".") - 2

You then handle TextPos being 4, 3, 2 or 1. But if, for example, TextBox4.Value = "2.22222" then TextPos = 0 and you have no code for that situation.

At 11:45 GMT, I suggested in a comment that dividing by 1000 would give you the result you seek. At 14:08 GMT, tunderblaster posted this as an answer. It is now 15:23 but you have not responded to either of us.

Having tried your code, I now know these answer do not match the result it gives when it works because you remove the sign. The following would give you almost the same as a working version of your code:

TextBox4.Value = Format(Abs(Val(TextBox4.Value)) / 1000, "#,##0.#########")

The only deficiency with this statement is that it does not preserve all the trailing decimal digits. Is this really important?

While I was preparing and posting this answer, you edited your question to state that dividing by 1000 would sometimes give the result in scientific format. My solution avoids that problem.

OTHER TIPS

It appears to me through all your edits that you want to divide the number by one thousand. To do this, you can simply use

TextBox4.Value = TextBox4.Value / 1000

If you want to avoid floating point error when dividing by 10, you may use the Decimal type

Private Sub CommandButton1_Click()
    Dim d As Variant
    d = CDec(TextBox1.Text)
    TextBox1.Text = d / 1000
End Sub

Is this what you are trying?

Sub Sample()
    Dim sNum As String, SFinal As String
    Dim sPref  As String, sSuff As String
    Dim nlen As Long

    sNum = "234.123123123123123123131231231231223123123"

    SFinal = sNum

    If InStr(1, sNum, ".") Then
        sPref = Trim(Split(sNum, ".")(0))
        sSuff = Trim(Split(sNum, ".")(1))
        nlen = Len(sPref)

        Select Case nlen
            Case 1: SFinal = ".00" & Val(sPref) & sSuff
            Case 2: SFinal = ".0" & Val(sPref) & sSuff
            Case 3: SFinal = "." & Val(sPref) & sSuff
        End Select
    End If

    Debug.Print SFinal
End Sub

Try this. It works by initialy padding the string with leading 0's, shifting the DP, then removing any unnecassary remaining leading 0's

Function ShiftDecimalInString(str As String, Places As Long) As String
    Dim i As Long
    If Places > 0 Then
        ' Move DP to left
        '  Pad with leading 0's
        str = Replace$(Space$(Places), " ", "0") & str

        ' Position of .
        i = InStr(str, ".")
        str = Replace$(str, ".", "")

        If i > 0 Then
            ' Shift . to left
            str = Left$(str, i - Places - 1) & "." & Mid$(str, i - Places)

            ' strip unnecassary leading 0's
            Do While Left$(str, 2) = "00"
                str = Mid$(str, 2)
            Loop
            If str Like "0[!.]*" Then
                str = Mid$(str, 2)
            End If

            ShiftDecimalInString = str
        Else
            ' No . in str
            ShiftDecimalInString = str
        End If
    ElseIf Places < 0 Then
        ' ToDo: Handle moving DP to right
    Else
        ' shift DP 0 places
        ShiftDecimalInString = str
    End If
End Function

This "answer" responses to the issue that you want as much precision in the result as possible.

When I was at school this was called spurious accuracy. I have forgotten most of my mathematics in this area but I will try to give you an understanding of the issue.

I have a value, 2.46, which is accurate to 2 decimal places. That is the true value is somewhere in the range 2.455 to 2.465.

If I feed these values into a square root function I will get:

sqrt(2.455) = 1.566843961599240
sqrt(2.46)  = 1.568438714135810
sqrt(2.465) = 1.570031846810760

From this I see the square root of the true value is somewhere between 1.567 and 1.570; any extra decimal digits are spurious.

If I understand correctly, you wish to use these numbers to make adjustments. Are you capable of making adjustments to 15 decimal digits?

If you remember your calculus you can look up "propogation of error" for a better explanation.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top