Updated on
Page Property: JavaScript
[Japanese Page]
Eng.Home
Tools
Programming
Doodle (Jpn)
Graphics
Misc
Gate
About Me
What's New
Links (Jpn)

[Back Home]
Back Home

Read First
Email

compass

Programming Clue.



If you want to manage something (text, csv-file, etc.) using SED, or some kind of probrem about programming, please e-mail me.
I might give you any ideas for solution. maybe.... :-)

Check Tools page, if you want to see any other samples.

I wrote these scripts or program codes with no harm, but I will not take on responsibility for their acts or for results (damage, losses etc.) by their acts or by using script/program. And I will not take on responsibility, too, for results by only having their copy without activating them.


Index

SED
When g-command doesn't work well
1. Replacement comma between double-quote to semi-colon in CSV file
2. Add comma into number every 3-digit
BASIC (include VBA), Pascal, C, Modula-2, etc.
1. Dynamic variable nesting loop
2. Function for integer to alphabetical "number"
(1) integer(1-702) to two digit alpahbetical number Num2Alpha
(2) integer(1-600) to two digit alpahbetical number (without "I" and "O") Num2Alpha2
3. Function to split string (rewrite from JavaScript version)
(1) strSplit(); substitute function for Split() on VBA for Excel 2000 or later version.
(2) strSplitG(); using array version; substitute function for Split() on VBA for Excel 2000 or later version.
4. Function to calculate age with VBA ; CalcAge & CalcAge2
5. Function to remove spaces at the both side of string and to shrink series of spaces within string
(rewrite from JavaScript version) xtrim in 2 ways
6...7 are omitted, because they are related to Japanese culture and written in Japanese, and probably unnecessary for English-speaking people.
8. Delete NewLine Characters in string and to trim spaces on edge of string, and to shrink series of spaces within string
(1) Function for VBA to delete NewLine Characters(=vbLf/vbCR/vbCRLF) and to trim spaces on edge of string, and to shrink series of spaces within string
(2) Procedure for VBA for Excel to delete NewLine Characters and to trim spaces and to shrink series of spaces within string within string in Selected Range on Excel Worksheet; simple application of (1)
9. Substitute function for Replace function introduced into Excel 2000 and later version strReplace()
JavaScript
1. function for splitting strings
(1) looks like split() method strSplit
(2) using array strSplitG
2. Transfer function for integral numeral to string
(1) decimal format toStr
(2) any radix format toStrExt
3. function to judge whether a string argument is a number or not isNum
:: [Evaluation Page]
(2) function to remove prefixed "+"(plus) sign dePlusSign
4. Function for integer to alphabetical "number" (translated from BASIC source #2)
(1) integer(1-702) to two digit alpahbetical number Num2Alpha
(2) integer(1-600) to two digit alpahbetical number (without "I" and "O") Num2Alpha2
5. Function to remove spaces from string
(1) Function to remove spaces in front of string (= left side of string) ltrim
(2) Function to remove spaces at the back of string (= right side of string) rtrim
(3) Function to remove spaces at the both side of string trim
(4) Function to remove spaces at the both side of string and to shrink series of spaces within string xtrim
6. Function to replace string strReplace
:: [Evaluation Page]


[SED Script]

When g-command doesn't work well [To Top][To Bottom]

When you use s command with g option like "s/pattern/replacement/g" to replace matched pattern repeatedly, s command sometimes lose pattern. It happens when pattern include a string that can be replaced with replacement. Because sed ignore a string that once replaced while s command is running (maybe it is to avoid occuring endless looping). So, you have to command again like following sample after a suceeded replacement.

Ex1.) Replacement comma between double-quote to semi-colon in CSV file.

:LOOP
    s/\("[^",][^",]*\),\([^"]*"\)/\1;\2/
    t LOOP
s/\(,"[^",]*","\),/\1;/g
s/\(,[^",]*,"\),/\1;/g
s/^",/";/

Ex2.) Add comma into number every 3-digit

s/\([0-9]\)\([0-9][0-9][0-9]\)$/\1,\2/
:LOOP
    s/\([0-9]\)\([0-9][0-9][0-9]\)\([^0-9]\)/\1,\2\3/
t LOOP

[BASIC, Pascal, C, Modula-2, etc.]

1. Dynamic variable nesting loop [To Top][To Bottom]

If you want to make variable nesting loop, try this way. You can make deep dyanamic nesting loops, such as thousand loops!, without writing many loops, without a lot of trouble. Sample is written in pascal.

program  VariableNestingLoop (input, output);
  var loopbegin, loopend : integer;
  var ns : array [1..MAXNESTING] of integer;
begin
    for i:=1 to nesting do ns[i] := loopbegin;
    repeat
        { ... some looping processes or
              procedure-/function-calls are here ... }
        i := nesting;
        ns[i] := ns[i] + 1;
        while ( ns[i] > loopend ) and ( i > 0 ) do begin
            ns[i] := loopbegin;
            i := i - 1;
            if i > 0 then
                ns[i] := ns[i] +1
        end
    until i = 0
end.

2. (1) Function for integer(1-702) to two digit alphabetical "number" [To Top][To Bottom]

This function is to transfer integer (from 1 to 702) to two digit alphabetical number (from "A" to "ZZ"); just like column index of Spreadsheet (e.g. MS-Excel/Lotus 1-2-3) such as series of A,B,C,...,Z,AA,AB,...,ZZ. At first sight, output "number" looks as 27 radix, but it isn't. Because this output string is "AA" for 27 instead of "A_". So this two digit alphabetical number expresses 702 at the most instead of 728 by 27 radix.
Following sample is written in Visual Basic for Application of MS-Excel. And JavaScript version of this function is below.

' Function for integer(1-702) to two digit alphabetical "number"  
' written by Seiji Fujita
' Output alphabetical numbers are A,B,C...,Z,AA,AB,...,ZZ.
' Notice: output is not 27 radix.
Function Num2Alpha(num As Integer) As String
    Dim upper As Integer
    Dim lower As Integer
    Const strRef = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"

    If (num <= 0) Or (num > 702) Then
        Num2Alpha = "ERR"
        Exit Function
    End If
    upper = (num - 1) \ 26
    lower = (num - 1) Mod 26 + 1
    If upper > 0 Then
        Num2Alpha = Mid(strRef, upper, 1) + Mid(strRef, lower, 1)
    Else
        Num2Alpha = Mid(strRef, lower, 1)
    End If
End Function

2. (2) Function for integer(1-600) to two digit alphabetical "number" [To Top][To Bottom]

This is almost the same as (1) except output string has not "I" and "O". This rule may use in product numbering to avoid confusion 1 with I, or 0 with O. Output alphabetical number are A,B,...,H,J,...,N,P,...,Z,AA,AB,...,AH,AJ,...,AN,AP,...AZ,...,HZ,JA,...,NZ,PA,...PZ,...,ZZ. Output is not 25 radix.

' Function for integer(1-600) to two digit alphabetical "number"  
' written by Seiji Fujita
' Output alphabetical numbers are A,B,...,H,J,...,N,P,...,Z,
' AA,AB,...,AH,AJ,...,AN,AP,...AZ,...,HZ,JA,...,NZ,PA,...PZ,...,ZZ.
' Notice: output is not 25 radix.
Function Num2Alpha2(num As Integer) As String
    Dim upper As Integer
    Dim lower As Integer
    Const strRef = "ABCDEFGHJKLMNPQRSTUVWXYZ"

    If (num <= 0) Or (num > 600) Then
        Num2Alpha = "ERR"
        Exit Function
    End If
    upper = (num - 1) \ 24
    lower = (num - 1) Mod 24 + 1
    If upper > 0 Then
        Num2Alpha = Mid(strRef, upper, 1) + Mid(strRef, lower, 1)
    Else
        Num2Alpha = Mid(strRef, lower, 1)
    End If
End Function

3. (1) Function to split string (rewrite from JavaScript version) [To Top][To Bottom]

This function can be used on VBA for Excel 97 (Of course this can be used on VBA for Excel 2003, or Word etc., too) as substitute for Split function on VBA for Excel 2000 or later version. strSplit() requires string argument src as a source, and a numeral argument pos as an index of output string and a string argument sep as a separator (delimiter). And it returns separated string that index is sep. sep is available from 0 to N-1 when src is separeted to N strings in amount. When string sep is not found in string src or when number pos is above amount of separated words, return value becomes "" (means "null").
Please read usage for that of JavaScript version "1. (1) function for splitting strings", too.
If you want to split string contains series of spaces by space, try to use xtrim function.

' substitute of Split for after VBA 2000
' pos is a number for pick up item, first number is zero (=0)
' return value is ""(=null) when pos is over separable number
' or when src does not contain sep.
' written by Seiji Fujita
' revised for sep is null(="")
Function strSplit(ByVal src As String, ByVal sep As String, ByVal pos As Long) As String
    Dim prePtr As Long
    Dim postPtr As Long
    Dim strWord As String
    Dim i As Long
    Dim flag As Boolean

    If sep <> "" Then
        i = 0
        flag = False
        Do While prePtr <= Len(src) And i <= pos
            If prePtr <= 0 Then
                postPtr = InStr(src, sep)
                prePtr = 1
            Else
                postPtr = InStr(prePtr, src, sep)
            End If
            If postPtr >= 1 Then
                strWord = Mid(src, prePtr, postPtr - prePtr)
                prePtr = postPtr + Len(sep)
            Else
                If i > 0 And flag = False Then
                    strWord = Mid(src, prePtr)
                Else
                    strWord = ""
                End If
                flag = True
            End If
            i = i + 1
        Loop
        If i <= pos Then
            strWord = ""
        End If
        strSplit = strWord
    Else
        strSplit = ""
    End If
End Function

3. (2) Function to split string using (global) array [To Top][To Bottom]

This function can be used on VBA for Excel 97 (Of course this can be used on VBA for Excel 2003, or Word etc., too) as substitute for Split function on VBA for Excel 2000 or later version.
This function returns amount of separated words (from 0). Return value equal 0 (zero) means that string sep is not found in string src, and the value of SplitWord(0)..SplitWord(NUM-1) becomes "null". Return value equal -1 means that number of maximum value is not enough for amount of separable words (separable number > NUM + 1), and the value of SplitWord(0)..SplitWord(NUM-1) signs right separated strings, but you cannot get strings that should be separated originally as SplitWord(NUM) or SplitWord(NUM+x)...
Please read usage for that of JavaScript version "1. (2) function for splitting strings; using array", too.

If you want strSplitG() to return SplitWord[0] as src when return value of strSplitG() = 0 (that means sep is not found in src), you should set true into notfound.

' substitute of Split for after VBA 2000 ; using array
' pos is a number for pick up item, first number is zero (=0)
' return value is ""(=null) when pos is over separable number
' or when src does not contain sep.
' written by Seiji Fujita
' revised for sep is null(="")
'
' If you want to be returned SplitWord(0)=src when return value strSplitG=0
' (= when src does not contain sep), set optional parameter notfound = true.
' If notfound = false or not used notfound at that sistuation, returned SplitWord(0)="".
'
' Return value strSplitG is separable number of src (more than 0).
' When return value strSplitG = 0 that means src does not contain sep,
' and values of SplitWord(0)...SplitWord(NUM-1) = "".
' when optional parameter notfound = False or default (not set notfound).
'
' If you want to be SplitWord(0) = src, when return value strSplitG = 0
' (that means src does not contain sep), set optional parameter notfound = True.
'
' When return value strSplitG = -1 that means NUM is too small for separable
' number of src (separable number > NUM + 1), at that time values of
' SplitWord(0)...SplitWord(NUM-1) is appropriate string, but you cannot get
' separated string on and after SplitWord(NUM).
'
' Decrare NUM as global constant (Public Const).
' Decrare array for SplitWord() in parent procedure/function.
Function strSplitG(ByVal src As String, ByVal sep As String, _
        ByRef SplitWord() As String, Optional notfound As Boolean) As Integer
    Dim prePtr As Long
    Dim postPtr As Long
    Dim strWord As String
    Dim i As Long
    Dim flag As Boolean

    Erase SplitWord

    If sep <> "" Then
        i = 0
        flag = False
        Do While prePtr <= Len(src) And flag = False And i <= NUM
            If prePtr <= 0 Then
                postPtr = InStr(src, sep)
                prePtr = 1
            Else
                postPtr = InStr(prePtr, src, sep)
            End If
            If postPtr >= 1 Then
                SplitWord(i) = Mid(src, prePtr, postPtr - prePtr)
                prePtr = postPtr + Len(sep)
            Else
                If i > 0 And flag = False Then
                    SplitWord(i) = Mid(src, prePtr)
                    prePtr = Len(src) + 1
                End If
                flag = True
            End If
            i = i + 1
        Loop
        If InStr(prePtr, src, sep) > 0 And i > NUM Then  '----(A)
            strSplitG = -1
        Else
            If i = 1 Then       ' And SplitWord(0) = ""
                strSplitG = 0
                If notfound = True Then
                    SplitWord(0) = src
                End If
            Else
                strSplitG = i
            End If
        End If
    Else
        strSplitG = 0
        If notfound = True Then
            SplitWord(0) = src
        End If
    End If
End Function

** You can write If-statement on line (A) as follows (same logic).
        If Len(Mid(src, prePtr)) > 0 And i > NUM Then
* Usage Sample
Public Const NUM As Integer = 20

Sub Sample()
    Dim SplitWord(NUM) As String
    Dim i As Integer
    Dim str As String

    MsgBox "Number of separation is: " & strSplitG("abcdefg", "c", SplitWord())

    str = "Result of separation: "
    For i = 0 To NUM
        str = str & CStr(i) & "=" & SplitWord(i) & " / "
    Next i
    MsgBox str
End Sub

* If you want Split function for Excel 97 VBA just like that for Excel 2000 VBA, Check web-page
SPLIT-funktion for Excel 97


4. Function to calculate age with VBA [To Top][To Bottom]

You can calculate age with DATEDIF of Excel worksheet function (* note), but you can not get same answer with similar function datediff of VBA in same manner (refer to [2004-06-24] Bug of MS Excel 97 function).

* [added on 2023-02-12] DATEDIF of Excel worksheet function also turned out to be wrong about leap years. It returns wrong age (1 less value) for February 28th in a normal year born on February 29th in a leap year (Confirmed with Excel 97, Excel 2003, Excel 2010, Office 365 Excel Online).

An extream examle to calculate age at January 1, 2007 for birthday December 31, 2006 using Datediff("yyyy","2006/12/31", "2007/01/01"), result is 1 instead of 0. This is a "specification" of VBA (I don't agree it, and I think it is a bug!). So it is necessary to manage to get right answer. (This strange spec took over from Excel 97 (maybe Excel 95 too) to Excel 2003.)

To get right age with CalcAge() in integer requires string argument daybirth as birthday in format yyyy/mm/dd (mm and/or dd can be 1-digit) and string argument fixday as date to fix age in format yyyy/mm/dd (mm and/or dd can be 1-digit). daybirth and fixday is needed in 1 byte code string. But this function retouch it into 1 byte code if they contain 2 byte code to avoid error. When calling from VBA, fixday can be given a date using the Date() function, Now() function, CDate() function, etc. (because they are automatically converted to strings).
When using this function like "=CalcAge(A1,B1)" on the worksheet, the date-related functions are not automatically converted to strings, so it is necessary to convert them like this: TEXT(NOW(),"YYYY/MM/DD") or TEXT(TODAY(),"YYYY/MM/DD"). The format can be "YYYY/M/D".; e.g.: write =CalcAge("2000/1/3",TEXT(TODAY(),"YYYY/MM/DD")) instead of =CalcAge("2000/1/3",TODAY()). Note that no special format specification is required when specifying a cell in which a date-related function has been assigned.; e.g.: You can write =CalcAge("2000/1/3",D10) when =TODAY() is assigned to cell D10.

For function IsLeapYear(), refer to the function described in Function to check whether the specified day is a holiday.

' This function calculate right age at appointment day in VBA
' daybirth, fixday are string in format yyyy/mm/dd (mm and/or dd can be 1-digit) 
' return value
'   if in normal: 0 or positive integer
'   if in abnormal: negative integer
'      daybirth or/and fixday are not in right format : -1
'      daybirth > fixday : -2
' Message Box shows when mgflag = True and return value < 0, 
' written by Seiji Fujita
' revised by Seiji Fujita on February 12, 2023
Function CalcAge(ByVal daybirth As String, ByVal fixday As String, _
        Optional ByVal msgflag As Boolean) As Integer
    Dim bmd As Integer
    Dim fmd As Integer

    ' convert parameter into 1 byte code if they contain 2 byte code
    daybirth = StrConv(daybirth, vbNarrow)
    fixday = StrConv(fixday, vbNarrow)

    If (IsDate(daybirth) And IsDate(fixday)) = False Then
        If msgflag = True Then
            MsgBox "parameter(s) is/are not in right format", vbCritical
        End If
        CalcAge = -1
        Exit Function
    End If

    If daybirth > fixday Then
        If msgflag = True Then
            MsgBox "fixday is older than daybirth", vbCritical
        End If
        CalcAge = -2
        Exit Function
    End If

    bmd = 100 * Month(daybirth) + Day(daybirth)
    fmd = 100 * Month(fixday) + Day(fixday)

    CalcAge = DateDiff("yyyy", daybirth, fixday)
    If CalcAge > 0 And fmd < bmd Then
        If IsLeapYear(Year(daybirth)) And bmd = 229 Then
            If Not (Not (IsLeapYear(Year(fixday))) And fmd = 228) Then
                CalcAge = CalcAge - 1
            End If
        Else
            CalcAge = CalcAge - 1
        End If
    End If

End Function

Examples

Sub Sample()
    MsgBox CalcAge("2006/12/31", "2007/01/01")  ' result = 0
    MsgBox CalcAge("2006/12/31", CDate("February 2, 2017")) ' result = 10
    MsgBox CalcAge("2006/12/31", CDate("2008-10-10")) ' result = 1
    MsgBox CalcAge("1964/2/29", CDate("2007-02-28")) ' result = 43
    MsgBox CalcAge("1964/2/29", CDate("2008-02-28")) ' result = 43
    MsgBox CalcAge("1964/2/29", CDate("2008-02-29")) ' result = 44
    MsgBox CalcAge("1980/10/10", "2005/06/02") ' result = 24
    MsgBox CalcAge("1980/10/10", Now())
    MsgBox CalcAge("1980/10/10", Date)
End Sub
* When using this function on the worksheet, TODAY() and NOW() must be given after converting the format as follows.
=CalcAge("1980/10/10", TEXT(NOW(),"YYYY/MM/DD"))
=CalcAge(A1, TEXT(TODAY(),"YYYY/M/D"))

* If you want to solve this without DateDiff function, code is like below here CalcAge2. Usage is same treatment as CalcAge.

' This function calculate right age at appointment day in VBA
' daybirth, fixday are string in format yyyy/mm/dd (mm and/or dd can be 1-digit) 
' return value
'   if in normal: 0 or positive integer
'   if in abnormal: negative integer
'      daybirth or/and fixday are not in right format : -1
'      daybirth > fixday : -2
' Message Box shows when mgflag = True and return value < 0, 
' written by Seiji Fujita
' revised by Seiji Fujita on February 12, 2023
Function CalcAge2(ByVal daybirth As String, ByVal fixday As String, _
        Optional ByVal msgflag As Boolean) As Integer
    Dim bmd As Long
    Dim fmd As Long
    Dim bymd As Long
    Dim fymd As Long

    ' convert parameter into 1 byte code if they contain 2 byte code
    daybirth = StrConv(daybirth, vbNarrow)
    fixday = StrConv(fixday, vbNarrow)

    If (IsDate(daybirth) And IsDate(fixday)) = False Then
        If msgflag = True Then
            MsgBox "parameter(s) is/are not in right format", vbCritical
        End If
        CalcAge2 = -1
        Exit Function
    End If

    bmd = 100 * Month(daybirth) + Day(daybirth)
    fmd = 100 * Month(fixday) + Day(fixday)
    bymd = 10000 * Year(daybirth) + bmd
    fymd = 10000 * Year(fixday) + fmd

    If IsLeapYear(Year(daybirth)) And bmd = 229 Then
        If Not (IsLeapYear(Year(fixday))) And fmd = 228 Then
            bymd = bymd - 1
        End If
    End If
    
    CalcAge2 = Int((fymd - bymd) / 10000)

    If CalcAge2 < 0 Then
        If msgflag = True Then
            MsgBox "fixday is older than daybirth", vbCritical
        End If
        CalcAge2 = -2
    End If

End Function

* It would be easier if you use the worksheet function DATEDIF of MS Excel, but unfortunately it returns wrong age (1 less value) for February 28th in a normal year born on February 29th in a leap year. This function will not work properly.
Note:Some websites suggest that you can fix the DATEDIF bug by adding +1 the end date, but that's pointless as you'd actually make a much more disastrous mistake. Without correction, the function would be wrong only once every 4 years for those born on February 29th. With adding +1 correction, the function would be wrong once every year for 365 days excluding February 29th. Example: Born on January 25, 1999, the correct age as of January 24, 2005 is 5 years old, but the result after adjusting by +1 is 6 years old).

' Function using Excel worksheet function; An error occurs in the calculation of leap years!
Function CalcAgeWithDatedif(ByVal daybirth As String, ByVal fixday As String) As Integer
    Dim strdf As String

    strdf = "DATEDIF(" & """" & bd & """" & "" & "," & """" & fd & """" & "," & """Y""" & ")"
    CalcAgeWithDatedif = Application.Evaluate(strdf)
End Function
For the above function, the command below should returns 3, but unfortunately it returns an incorrect 2.
    MsgBox CalcAgeWithDatedif("1964/2/29", "1967/2/28") ' returns 2 instead of 3



5. Function to remove spaces at the both side of string and to shrink series of spaces within string (rewrite from JavaScript version) xtrim in 2 ways [To Top][To Bottom]

(1) Please read usage for that of JavaScript version "5. (4) function for splitting strings" following. Note: You don't prepare trim/ltrim/rtrim function, because VBA has same functions.

Example usage: Split(xtrim(srcstring)," ") to split words from string contains one or more series of spaces.

' Function to remove spaces at the both side of string and to shrink series of spaces within string
' written by Seiji Fujita
Function xtrim(ByVal s As String) As String
    Dim p As Integer
    Dim tmp As String

    s = Trim(s)
    p = 1
    Do While p < Len(s)
        If Mid(s, p, 1) = " " Then
            s = Left(s, p - 1) & " " & Trim(Mid(s, p + 1))
        End If
        p = p + 1
    Loop
    xtrim = s
End Function

If you manage 2byte spaces in string, check xtrim for 2byte code.

(2) You can write more easy way as following, but it works only with Excel.
Note: This function does not work with VBA of Word or that of Access etc.

' Function to remove spaces at the both side of string and to shrink series of spaces within string
' using worksheet's function 'trim'
' Note: this works only with Excel
Function xtrim(ByVal s As String) As String
    Application.Trim(s)
End Function

6. and 7. are omitted.

#6 and #7 are omitted, because they are related to Japanese culture and written in Japanese, and probably unnecessary for English-speaking people.


8. (1) Function for VBA to delete NewLine Characters(=vbLf/vbCR/vbCRLF) and to trim spaces on edge of string, and to shrink series of spaces within string [To Bottom]

This function needs Replace function in VBA of Excel 2000 or later (therefore this function doesn't work with VBA of Excel 97)
Note1: If some use trouble when replace NewLine to Null string, rewrite third parameter of Replace function from "" to " ".
Note 2: If you want to use this function in Excel 97, use/define strReplace, and replace Replace in following code into strReplace.

' Function to delete NewLine Characters(=vbLf/vbCR/vbCRLF)
' and to trim spaces on edge of string,
' and to shrink series of spaces within string.
' xtrim is a function that is opened in this page.
Function DeleteCRAndTrimSPC(ByVal str As String) As String

    str = Replace(str, vbLf, "")
    str = Replace(str, vbCr, "")
    str = Replace(str, vbCrLf, "")
    DeleteCRAndTrimSPC = xtrim(str)
End Function

8. (2) Procedure for VBA for Excel to delete NewLine Characters(=vbLf/vbCR/vbCRLF) and to trim spaces on edge of string, and to shrink series of spaces within string in Selected Range on Excel Worksheet [To Bottom]

This is a simple application of section 8. (1). You need select range (=worksheet cells) manually or automatically before call this function. If you need strictness, (a) you should activate applicable workbook or worksheet before call this procedure, or (b) you should rewrite "In Selection" in this function into "In ActiveSheet.Selection" or "In ActiveWorkbook.ActiveSheet" etc. not to this procedure touch unsuitable range.
Note: Actually, NewLine in Cell is vbLF only.

' Procedure to delete NewLine Characters(=vbLf/vbCR/vbCRLF)
' and to trim spaces on edge of string,
' and to shrink series of spaces within string.
' You should select range  before call this function.
Sub DeleteCRAndTrimSPCInSelection()
    Dim rng As Range

    For Each rng In Selection
        rng.Value = DeleteCRAndTrimSPC(rng.Value)
    Next rng
End Sub

* For practical use, you should limit range in selection to process efficintly, using intersect(), just like followings.
  Intersect(Selection, Cells.SpecialCells(xlCellTypeConstants, xlTextValues))
Note: You have to write error trap when result of intersection is nothing.


9. Substitute function for Replace function introduced into Excel 2000 and later version [To Top][To Bottom]

This function can be used on VBA for Excel 97 (Of course this can be used on VBA for Excel 2003, or Word etc., too) as substitute for Replace function on VBA for Excel 2000 or later version.
This function replaces string src in str by string dst.
When dst is empty (= ""), this function work as delete src in str.

' Substitute function for Replace function introduced into Excel 2000 (for Excel 97)
Function strReplace(ByVal str As String, _
        ByVal src As String, ByVal dst As String) As String
    Dim lStr As Integer, lSrc As Integer
    Dim sLeft As String, sRight As String
    Dim ptr As Integer

    lStr = Len(str)
    lSrc = Len(src)
    sRight = str
    ptr = InStr(str, src)
    If lStr > 0 And lSrc > 0 And ptr > 0 Then
        Do While ptr > 0
            sLeft = sLeft & Left(sRight, ptr - 1) & dst
            sRight = Mid(sRight, ptr + lSrc)
            ptr = InStr(sRight, src)
        Loop
    End If
    strReplace = sLeft + sRight
End Function

[JavaScript]

1. (1) function for splitting strings ; looks like split() method [To Top][To Bottom]

If you want to split strings by JavaScript with Netscape Navigator 3.0 (NN3), you can use split() method. But with Microsoft Internet Explorer 3.xx (MSIE3), you cannot use it. Then try to use strSplit() function (follows). This function works both with NN3 and with MSIE3. strSplit() requires string argument src as a source, and a numeral argument pos as an index of output string and a string argument sep as a separator (delimiter). And it returns separated string that index is sep. sep is available from 0 to N-1 when src is separeted to N strings in amount. When string sep is not found in string src or when number pos is above amount of separated words, return value becomes "null".

/*
 * split() for Internet Explorer 3.xx
 * and for Netscape Navigator/Communicator
 * written by Seiji Fujita
 */
function strSplit(src , sep , pos) {
    var strWord = null;
    var prePtr = 0;
    var postPtr = 0;
    var i = 0;
    var flag = false;

    if (sep != '') {
        while((prePtr < src.length) && (i <= pos)) {
            postPtr = src.indexOf(sep, prePtr);
            if (postPtr >= 0) {
                strWord = src.substring(prePtr , postPtr);
                prePtr = postPtr + sep.length;
            } else {
                if ((i > 0) && (flag == false)) {
                    strWord = src.substring(prePtr , src.length);
                } else {
                    strWord = null;
                }
                flag = true;
            }
            i++;
        }
        if (i <= pos) {
            strWord = null;
        }
        return strWord;
    } else {
        return null;
    }
}

Examples

var vString = "A Quick brown fox jumps over the lazy dog.";
var vStr4th = strSplit(vString, " ", 3);
var vStr7th = strSplit(vString, " ", 6);
var vStr9th = strSplit(strSplit(vString, " ", 8),".", 0);
var vStr10th = strSplit(vString, " ", 9);

Results

A value of vStr4th becomes "fox" and a value of vStr7th becomes "the" and a value of vStr9th becomes "dog" and a value of vStr10th becomes "null".


1. (2) function for splitting strings ; using array [To Top][To Bottom]

When you split string by strSplit() with same string as src and same sapearator (delimiter) as sep, it took useless time. This function strSplitG() outputs separated words to global array SplitWord, it makes calculating time short until splitting by strSplitG() with another string or with another separator (* But if you need to change src or sep every time to call function, strSplit() may be fast). This function needs to be prepared array SplitWord in parent function, and it's element number needs to be larger than number of separable words.
This function returns amount of separated words (from 0). Return value equal 0 (zero) means that string sep is not found in string src, and the value of SplitWord[0]..SplitWord[NUM-1] becomes "null". Set parameter notfound = false.
** If you want to be returned SplitWord[0]=src when return value equal 0 (means src does not contain sep), set parameter notfound = true.
Return value equal -1 means that number of maximum value is not enough for amount of separable words (separable number > NUM + 1), and the value of SplitWord[0]..SplitWord[NUM-1] signs right separated strings, but you cannot get strings that should be separated originally as SplitWord[NUM] or SplitWord[NUM+x]...
This function works both with NN3 and with MSIE3.

/*
 * split() for Internet Explorer 3.xx
 * and for Netscape Navigator/Communicator
 * written by Seiji Fujita
 *
 * Need to declare as var SplitWord = new Array(NUM); in parent function().
 *    NUM: set some integer. (enought larger than maximum expected)
 *
 * (If you want to use SplitWord as global array, 
 *  replace declare part with one of followings.
 *
 *  function strSplitG(src, sep, notfound) {
 *
 * notfound = false
 *   When return value = 0 (means not found sep in src), SplitWord[0] = null
 * notfound = true
 *   When return value = 0 (means not found sep in src), SplitWord[0] = src
*/
function strSplitG(src, sep, SplitWord, notfound) {
    var prePtr = 0.0;
    var postPtr = 0.0;
    var flag = false;

    for (var i=0; i < NUM; i++) {
        SplitWord[i] = null;
    }
    if (sep != '') {
        i = 0;
        while((prePtr < src.length) && (flag == false) && (i < NUM)) {
            postPtr = src.indexOf(sep, prePtr);
            if (postPtr >= 0) {
                SplitWord[i] = src.substring(prePtr, postPtr);
                prePtr = postPtr + sep.length;
            } else {
                if ((i > 0) && (flag == false)) {
                    SplitWord[i] = src.substring(prePtr, src.length);
                    prePtr = src.length + 1;
                }
                flag = true;
            }
            i++;
        }
        if ((src.indexOf(sep, prePtr) >= 0) && (i >= NUM)) {
            return -1;
        } else {
            if (i == 1) {       //or if ((i ==1) && (SplitWord[0] == null))
                if (notfound) {
                    SplitWord[0] = src;
                }
                return 0;
            } else {
                return i;
            }
        }
    } else {
        return 0;
    }
}

Examples

var NUM = 10;
var vWord = new Array(NUM);
var vString = "A Quick brown fox jumps over the lazy dog.";
var vCount = strSplitG(vString, " ", vWord, false);
var vStr4th = vWord[3];
var vStr7th = vWord[6];
var vStr9th = vWord[8];
var vStr20th = vWord[19];

Results

A value of vCount becomes "9" and a value of vStr4th becomes "fox" and a value of vStr7th becomes "the" and a value of vStr9th becomes "dog." and a value of vStr20th becomes "null".
* When you set vWord's parameter that larger than NUM, return value is undefined (Example: when NUM=10, vWord[20] = undefined)


2. (1) Transfer function for integral numeral to string (decimal format) [To Top][To Bottom]

If you want to change numeral to string by JavaScript with Netscape Navigator 3.0 (NN3), you can use toString() method. But with Microsoft Internet Explorer 3.xx (MSIE3), you cannot use it. Then try to use toStr() function (follows). This function works both with NN3 and with MSIE3. toStr() requires an integral numeral argument vNum as an integer, and returns an equivalent string. This sample has no error processes whether vNum is a number or not. If you need an error correction, add it by yourself.

/*
 * toString() for Internet Explorer 3.xx 
 * and for Netscape Navigator/Communicator
 * written by Seiji Fujita
*/
function toStr(vNum) {
    var vRef = "0123456789";
    var vtmpStr = "";
    var vtmpNum = 0;
    var vMinus = false;
    if (vNum < 0) {
        vMinus = true;
        vNum = -vNum;
    }
    var vlen = Math.floor( Math.log(vNum) / Math.log(10) ) + 1;
    for ( i = 1; i <= vlen; i++ ) {
        vtmpNum = vNum % 10;
        vNum = Math.floor(vNum / 10);
        vtmpStr = vRef.charAt(vtmpNum) + vtmpStr;
    }
    if (vMinus)
        vtmpStr = "-" + vtmpStr;
    return vtmpStr;
}

Examples

var vNum1 = 12;
var vNum2 = 50;
var vAdd1 = vNum1 + vNum2;
var vAdd2 = toStr(vNum1) + toStr(vNum2);

Results

A vAdd1's value becomes 62 (numeral) and a vAdd2's value becomes "1250" (string).


2. (2) Transfer function of integral numeral to string (any radix from 2 to 36) [To Top][To Bottom]

This is an extension of toStr() for any radix format (from 2 to 36). This function works both with NN3 and with MSIE3. radix should be an integer such as "10" as decimal or "0x0a" as hexadecimal or "012" as octal. vNum should be an integer. If you give a float value to vNum, it will be fixed to as an integer, but its result is not guaranteed. This sample has no error processes whether vNum is a number or not, or whether radix is an integer or not, and so on. If you need an error correction, add it by yourself.
Note:Output string has no mark that shows its radix such as prefix "0x". So if you change a decimal number "255" to hexadecimal format, output value looks as "ff" instead of "0xff".

/*
 * toString() for Internet Explorer 3.xx 
 * and for Netscape Navigator/Communicator
 * written by Seiji Fujita
*/
function toStrExt(vNum, radix) {
    var vRef = "0123456789abcdefghijklmnopqrstuvwxyz";
    var vtmpStr = "";
    var vtmpNum = 0;
    var vMinus = false;
    if (vNum < 0) {
        vMinus = true;
        vNum = -vNum;
    }
    var vlen = Math.floor( Math.log(vNum) / Math.log(radix) ) + 1;
    for ( i = 1; i <= vlen; i++ ) {
        vtmpNum = vNum % radix;
        vNum = Math.floor(vNum / radix);
        vtmpStr = vRef.charAt(vtmpNum) + vtmpStr;
    }
    if (vMinus)
        vtmpStr = "-" + vtmpStr;
    return vtmpStr;
}

Examples

var vNum1 = 12;
var vNum2 = 50;
var vAdd1 = vNum1 + vNum2;
var vAdd2 = toStrExt(vNum1,8) + toStrExt(vNum2,0x10);

Results

A vAdd1's value becomes 62 (numeral) and a vAdd2's value becomes "1432" (string).


3. function to judge whether a string argument is a number or not [To Top][To Bottom]

If you want to judge whether a string argument is a number (decimal or hexadecimal or octal) or not by JavaScript, you can use parseFloat() or parseInt(). But their false value is different between with Netscape Navigator 3.0 (NN3) and with NN2, such as a special string "NaN" with NN3 and numeral 0 (zero) with NN2. Their false value with Microsoft Intenet Explorer 3.xx (MSIE3) is 0, same as with NN2. So you cannot use same function to judge argument. Then try to use isNum() function (follows). This function works with NN2, NN3 and MSIE3. isNum() requires a string argument vInStr as a source, and returns a boolean value with true or false as judge whether vInStr can be estimated number (decimal or hexadecimal or octal) or not.
This function ignores 1byte spaces in the front/rear of string by trim function mentioned later, so you have to declare ltrim, rtrim, trim to use isNum function.

[Sep 9, 2003] Revised for missusing such as inputting numeric or spaces into vInStr rather than numeral string.

/*
 * isNum() to judge string as if decimal / hexadecimal / ocatal or not
 * for Netscape Navigator/Communicator and Microsoft Internet Explorer
 * written by Seiji Fujita
 * return value is true or false as boolean
*/
function isNum(vInStr) {
    var vRefDec = "0123456789";
    var vRefOct = "01234567";
    var vRefHex = "0123456789abcdefABCDEF";
    var vRefSgn = "+-";
    var vRefExp = "eE";
    var judge = true;
    var vExp = false;
    var vExpSgn = false;
    var vPeriod = false;

    var vIn = "";
    vIn = vIn + vInStr;
    vIn = trim(vIn);
    var vlen = vIn.length;
    if ( vRefSgn.indexOf(vIn.charAt(0)) >= 0 ) {
        vIn = vIn.substring(1,vlen);
        vlen = vIn.length;
    }
    var i = 0;
    isHex = vIn.indexOf("0x");
    if (vlen == 0) {
        judge = false;
    } else if ( isHex >= 0 ) {
        if ( isHex >= 1 )
            judge = false;
        else {
            vIn = vIn.substring(2,vlen);
            vlen = vIn.length;
        }
        while ( (judge) && (i < vlen) ) {
            if ( vRefHex.indexOf(vIn.charAt(i) ) < 0 )
                judge = false;
            i++;
        }
    } else if ( (vIn.charAt(0) == "0")
            && ( vIn.charAt(1) != "." ) ) {
        while ((judge) && (i < vlen)) {
            if (vRefOct.indexOf(vIn.charAt(i)) < 0)
                judge = false;
            i++;
        }
    } else {
        while ( (judge) && (i < vlen) ) {
            if ( vRefDec.indexOf(vIn.charAt(i)) < 0 ) {
                if ( vRefSgn.indexOf(vIn.charAt(i) ) >= 0 )
                    if ((i <= 1) || (i == vlen-1))
                        judge = false;
                    else if ( !(vExpSgn) && (vExp) && (i >= 2) )
                        vExpSgn = true;
                    else
                        judge = false;
                else if ( vIn.charAt(i) == "." )
                    if ( !(vPeriod) && !(vExp) && (i < vlen-1) )
                        vPeriod = true;
                    else
                        judge = false;
                else if ( !(vExp) && (i > 0) && (i < vlen-1)
                        && (vRefExp.indexOf(vIn.charAt(i)) >= 0) )
                        vExp = true;
                    else
                        judge = false;
            }
            i++;
        }
    }
    return judge;
}

Examples & Results

isNum("  -1500")         // true
isNum("-15.00")          // true
isNum("  +15.00   ")     // true [*]
isNum("  +15.00-")       // false
isNum("  +15.00e+3")     // true [*]
isNum("      15.00e5")   // true
isNum("15.00e-15")       // true
isNum("  +15.00e+35")    // true [*]
isNum("  15.00e3.5")     // false
isNum("  +15.00e+3.5")   // false
isNum("  -0xfe+a")       // false
isNum("  -0xfega")       // false
isNum("  +0x3aea")       // true [*]
isNum("  +0x3AeA")       // true [*]
isNum("  +0x3a.ea")      // false
If you want to evaluate isNum(), go to [Evaluation Page].

3. (2) function to remove prefixed "+"(plus) sign [To Top][To Bottom]

Numeral strings with "true [*1]" in examples & results of 3.(1) are estimated as a number, but each of them causes error, when it use as an argument of eval() function with NN3 (or maybe NN2), because of prefixed "+"(plus) sign. I don't know why. With MSIE, eval() works right. So before using eval(), you should remove prefixed "+"(plus) sign. Because it is wastes your codes and times to check whether your visitor's browser is NN3 or not whenever you use eval() function. Following sample function is to remove prefixed "+"(plus) sign for NN2/NN3 and MSIE3. eval() ignores 1byte spaces in the front/rear of string, but this dePlusSign function removes them, by using trim function mentioned later, so you have to declare ltrim, rtrim, trim to use dePlusSign function.

* Using Netscape Navigator 4.78, you can get right answers when you substitute numeral strings with plus sign to eval(). That's the same with Opera 7.11.

/*
 * function to remove prefixed "+"(plus) sign
 * written by Seiji Fujita
*/ 
function dePlusSign(vInStr) {
    var vlen = vInStr.length;
    vInStr = trim(vInStr);
    if (vInStr.charAt(0) == "+") 
        vInStr = vInStr.substring(1,vlen);
    return vInStr;
}

Example

var a = eval(dePlusSign("+3.55e5"));
If you want to evaluate dePlusSign(), go to [Evaluation Page].

2. (1) Function for integer(1-702) to two digit alphabetical "number" (JavaScript version)[To Top][To Bottom]

This function is to transfer integer (from 1 to 702) to two digit alphabetical number (from "A" to "ZZ"); just like column index of MS-Excel etc such as series of A,B,C,...,Z,AA,AB,...,ZZ. At first sight, output "number" looks as 27 radix, but it isn't. Because this output string is "AA" for 27 instead of "A_". So this two digit alphabetical number expresses 702 at the most instead of 728 by 27 radix.
Visual BASIC for Application version of this function is above.

/* Function for integer(1-702) to two digit alphabetical "number"
 * written by Seiji Fujita
 * Output alphabetical numbers are A,B,C...,Z,AA,AB,...,ZZ.
 * Notice: output is not 27 radix.
 */
function Num2Alpha(num) {
    var upper = 0;
    var lower = 0;
    var Ref = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    var tmp = 0;

    if ((num <= 0) || (num > 702))
        return "ERR";
    upper = Math.floor( (num - 1) / 26);
    lower = (num - 1 ) % 26 + 1;
    if (upper > 0)
        tmp = Ref.charAt(upper - 1) + Ref.charAt(lower - 1);
    else
        tmp = Ref.charAt(lower - 1);
    return tmp;
}

2. (2) Function for integer(1-600) to two digit alphabetical "number" (JavaScript version)[To Top][To Bottom]

This is almost the same as (1) except output string has not "I" and "O". This rule may use in product numbering to avoid confusion 1 with I, or 0 with O. Output alphabetical numbers are A,B,...,H,J,...,N,P,...,Z,AA,AB,...,AH,AJ,...,AN,AP,...AZ,...,HZ,JA,...,NZ,PA,...PZ,...,ZZ. Output is not 25 radix.

/* Function for integer(1-600) to two digit alphabetical "number"  
 * written by Seiji Fujita
 * Output alphabetical numbers are A,B,...,H,J,...,N,P,...,Z,
 * AA,AB,...,AH,AJ,...,AN,AP,...AZ,...,HZ,JA,...,NZ,PA,...PZ,...,ZZ
 * Notice: output is not 25 radix.
 */
function Num2Alpha2(num) {
    var upper = 0;
    var lower = 0;
    var Ref = "ABCDEFGHJKLMNPQRSTUVWXYZ";
    var tmp = 0;

    if ((num <= 0) || (num > 600))
        return "ERR";
    upper = Math.floor( (num - 1) / 24);
    lower = (num - 1 ) % 24 + 1;
    if (upper > 0)
        tmp = Ref.charAt(upper - 1) + Ref.charAt(lower - 1);
    else
        tmp = Ref.charAt(lower - 1);
    return tmp;
}

5. Function to remove spaces from string[To Top][To Bottom]

(1) Function to remove spaces in front of string (= left side of string)

/* function to remove spaces in front of string */
function ltrim(vInStr) {
    var vlen = vInStr.length;
    while (vInStr.charAt(0) == " ") {
        vInStr = vInStr.substring(1,vlen);
        vlen = vInStr.length;
    }
    return vInStr;
}

(2) Function to remove spaces at the back of string (= right side of string)

/* function to remove spaces at the back of string */
function ltrim(vInStr) {
    var vlen = vInStr.length;
    while (vInStr.charAt(0) == " ") {
        vInStr = vInStr.substring(1,vlen);
        vlen = vInStr.length;
    }
    return vInStr;
}

(3) Function to remove spaces at the both side of string

This function uses ltrim, rtrim shown above, so you need declare these functions to use this function.

/* function to remove spaces in front of/ at the back of string
 * written by Seiji Fujita
 */ 
function trim(vInStr) {
    return ltrim(rtrim(vInStr));
}

(4) Function to remove spaces at the both side of string, and to shrink series of spaces within string

This function uses trim shown above, so you need declare ltrim, rtrim and trim functions to use this function.

/* function to remove spaces in front of/ at the back of string
 * and to shrink series of spaces within string into a space.
 * written by Seiji Fujita
 */ 
function xtrim(vInStr) {
    vInStr = trim(vInStr);
    var i = 1;
    while (i < vInStr.length) {
        if ((vInStr.charAt(i) == " ") && (vInStr.charAt(i+1) == " ")) {
            vInStr = vInStr.substring(0, i) + " " + vInStr.substring(i+2, vInStr.length);
        } else {
            i++;
        }
    }
    return vInStr;
}

If you manage 2byte spaces in string, check xtrim for 2byte code.


6. Function to replace string[To Top][To Bottom]

If you want to replace string by JavaScript with Microsoft Internet Explorer 4.xx (MSIE4) or Netscape Navigator 4.xx (NN4) or later version, you can use replace() method. But with older web browser such as MSIE3.xx or NN3.xx, you cannot use it. Then try to use strReplace() function (follows). This function replaces string ssrc in strOrg by string sdest.
When sdest is empty, this function work as delete ssrc in strOrg.
When gflag is true, replace every string matched ssrc, when gflag is false, replace first string matched ssrc only.
When iflag is true, ignore case distinctions in both "ssrc" and "strOrg".
If ssrc is not found in strOrg, return value is strOrg as it is. This function consider not to replace recursively, such as replacement string with same string (replace "a" by "a" or by "abc")

/* replace string function
 * written by Seiji Fujita
 *
 * Replace string "ssrc" in strOrg by "sdest".
 * If ssrc is not found in strOrg, return value is strOrg as it is.
 * gflag = false : replace first string matched "ssrc" only.
 *       = true  : replace every string matched "ssrc".
 * iflag = true  : ignore case distinctions in both "ssrc" and "strOrg".
 */
function strReplace(strOrg, ssrc, sdest, gflag, iflag) {
    var slOrg = strOrg.length;
    var slSrc = ssrc.length;
    var sleft = "";
    var sright = strOrg;
    if (iflag) {
        var sisrc = ssrc.toLowerCase();
        var pos = strOrg.toLowerCase().indexOf(sisrc);
        if ((slOrg > 0) && (slSrc > 0) && (pos >= 0)) {
            while(pos >= 0) {
                sleft = sleft + sright.substring(0, pos) + sdest;
                sright = sright.substring(pos + slSrc, slOrg);
                slOrg = sright.length;
                pos = sright.toLowerCase().indexOf(sisrc);
                if (!gflag) {
                    pos = -1;
                }
            }
        }
    } else {
        var pos = strOrg.indexOf(ssrc);
        if ((slOrg > 0) && (slSrc > 0) && (pos >= 0)) {
            while(pos >= 0) {
                sleft = sleft + sright.substring(0, pos) + sdest;
                sright = sright.substring(pos + slSrc, slOrg);
                slOrg = sright.length;
                pos = sright.indexOf(ssrc);
                if (!gflag) {
                    pos = -1;
                }
            }
        }
    }
    return sleft + sright;
}
If you want to evaluate strReplace(), go to [Evaluation Page].

* If you don't consider older web browser, you can write replacement function with (a) string.split() method and string.join() method, or (b) regular expression object RegExp() and string.replace() method.


[Eng.Home] | [Tools] | [Programming] | [Doodle] | [Graphics] | [Misc] | [Gate] | [About Me] | [Links]
[To Top]