поведение возврата каретки userforms vba

у многих ответов были полезные идеи, но ни один из них не соответствовал моим потребностям. Поэтому я использовал все идеи и создал этот пример:

function Format_Numb( fmt){
    var decimals = isNaN(decimals) ? 2 : Math.abs(decimals);
    if(typeof decSgn==="undefined") decSgn = ".";
    if(typeof kommaSgn==="undefined") kommaSgn= ",";

    var s3digits=/(\d{1,3}(?=(\d{3})+(?=[.]|$))|(?:[.]\d*))/g;
    var dflt_nk="00000000".substring(0,decimals);

    //--------------------------------
    // handler for pattern: "%m"
    var _f_money= function( v_in){
                var v=v_in.toFixed(decimals);
                var add_nk=",00";
                var arr=    v.split(".");
                return     arr[0].toString().replace(s3digits, function ([110]) {
                                    return ([110].charAt(0)==".")
                                        ? ((add_nk=""),(kommaSgn + [110].substring(1)))
                                        : ([110] + decSgn);
                        })
                        + (    (decimals > 0)
                                ?    (    kommaSgn
                                        + (
                                            (arr.length > 1)
                                            ? arr[1]
                                            : dflt_nk
                                        )
                                    )
                                :    ""                    
                        );
    }

    // handler for pattern: "%<len>[.<prec>]f"
    var _f_flt= function( v_in,l,prec){
        var v=(typeof prec !== "undefined") ? v_in.toFixed(prec):v_in;
        return ((typeof l !== "undefined")&&( (l=l-v.length) > 0))
                ?(Array(l+1).join(" ") + v)
                :v;
    }

    // handler for pattern: "%<len>x"
    var _f_hex= function( v_in,l,flUpper){
        var v=    Math.round(v_in).toString(16);
        if(flUpper)    v=v.toUpperCase();
        return ((typeof l !== "undefined")&&( (l=l-v.length) > 0))
                ?(Array(l+1).join("0") + v)
                :v;        
    }

    //...can be extended..., just add the function, f.e.:    var _f_octal= function( v_in,...){
    //--------------------------------

    if( typeof(fmt)!=="undefined"){
        //...can be extended..., just add the char,f.e."O":    MFX -> MFXO
        var rpatt=/(?:%([^%"MFX]*)([MFX]))|(?:"([^"]*)")|("|%%)/gi;
        var _qu=    "\"";
        var _mask_qu=    "\\\"";
        var str=    fmt.toString().replace( rpatt,function([110],$1,$2,$3,$4){
                                var f;
                                if(typeof $1 !== "undefined"){
                                    switch($2.toUpperCase()){
                                        case "M":    f= "_f_money(v)";    break;
                                        case "F":    var    n_dig0,n_dig1;
                                                var    re_flt=/^(?:(\d))*(?:[.](\d))*$/;
                                                $1.replace(re_flt,function([110],$1,$2){
                                                    n_dig0=$1;
                                                    n_dig1=$2;
                                                });
                                                f= "_f_flt(v," + n_dig0 + "," + n_dig1 + ")";    break;
                                        case "X":    var    n_dig="undefined";
                                                var    re_flt=/^(\d*)$/;
                                                $1.replace(re_flt,function([110]){
                                                    if([110]!="")n_dig=[110];
                                                });
                                                f= "_f_hex(v," + n_dig + "," + ($2=="X") + ")";    break;
                                        //...can be extended..., f.e.:    case "O":
                                    }
                                    return "\"+"+f+"+\"";
                                } else if(typeof $3 !== "undefined"){
                                    return _mask_qu + $3 + _mask_qu;
                                } else {
                                    return ($4==_qu)?_mask_qu:$4.charAt(0);
                                }
                            });
        var cmd=        "return function(v){"
                +        "if(typeof v === \"undefined\")return \"\";"    //null returned as empty string
                +        "if(!v.toFixed)return v.toString();"        //not numb returned as string
                +        "return \"" + str + "\";"
                +    "}";

        //...can be extended..., just add the function name in the 2 places:
        return new Function( "_f_money,_f_flt,_f_hex", cmd)(_f_money,_f_flt,_f_hex);
    }
}

Во-первых, мне нужно было определение формата строки в стиле C , которое должно быть гибким, но очень простым использовать , и я определил его следующим образом; паттерны:

%[<len>][.<prec>]f        float, example "%f", "%8.2d", "%.3f"
%m                        money
%[<len>]x                 hexadecimal lower case, example "%x", "%8x"
%[<len>]X                 hexadecimal upper case, example "%X", "%8X"

, поскольку нет необходимости форматировать другие, тогда как для меня Евро, я реализовал только "% m". Но это легко расширить ... Как и в C, строка формата - это строка, содержащая шаблоны, например. для евро : «% m €» (возвращает строки типа «8.129,33 €»)

Помимо гибкости, мне нужно было очень быстрое решение для таблицы обработки . Это означает, что при обработке тысяч ячеек обработку строки формата нельзя выполнять более одного раза . Вызов типа "format (value, fmt)" для меня неприемлем, но его нужно разделить на два этапа:

// var formatter = Format_Numb( "%m €");  
//simple example for Euro...

//   but we use a complex example: 

var formatter = Format_Numb("a%%%3mxx \"zz\"%8.2f°\"  >0x%8X<");

// formatter is now a function, which can be used more than once (this is an example, that can be tested:) 

var v1= formatter( 1897654.8198344); 

var v2= formatter( 4.2); 

... (and thousands of rows)

Также для производительности _f_money заключает в себе регулярное выражение;

В-третьих, вызов типа «format (value, fmt)» неприемлем, потому что: хотя должна быть возможность форматировать разные коллекции объектов (например, ячеек столбца) с разными масками, я не хочу, чтобы что-то обрабатывалось форматирование строк в точке обработки. На данный момент я хочу только использовать форматирование, как в

для (var cell in cell) {do_something (cell.col.formatter (cell.value)); }

Какой формат - может быть, он определен в ini, в xml для каждого столбца или где-то еще ..., но анализирует и устанавливает форматы или имеет дело с интернационализацией ] обрабатывается в совершенно другом месте , и там я хочу назначить средство форматирования для коллекции, не думая о проблемах производительности:

col.formatter = Format_Numb (_getFormatForColumn (...)) ;

В-четвертых, я хотел «толерантное» решение , поэтому прохождение fe строка вместо числа должна возвращать просто строку, но «null» должна возвращать пустую строку.

(Также форматирование «% 4.2f» не должно обрезать что-либо, если значение слишком велико.)

И последнее, но не менее важное: оно должно быть читаемым и легко расширяемым , БЕЗ оказывает какое-либо влияние на производительность ... Например, если кому-то нужны "восьмеричные значения", пожалуйста, обратитесь к строкам со словами "... можно расширить ..." - я думаю, что это должно быть очень простой задачей.

Я сосредоточился на производительности. Каждая «процедура обработки» (например, _f_money) может быть инкапсулирована, оптимизирована или заменена другими идеями в этом или других потоках без изменения «процедур подготовки» (анализа строк формата и создания функций), которые должны обрабатываться только один раз и в этом смысл не настолько критичен по производительности, как конверсионные вызовы тысяч номеров.

Для всех, кто предпочитает методы чисел:

Number.prototype.format_euro=( function(formatter){
    return function(){ return formatter(this); }})
    (Format_Numb( "%m €"));

var v_euro= (8192.3282).format_euro(); //results: 8.192,33 €

Number.prototype.format_hex= (function(formatter){
    return function(){ return formatter(this); }})
    (Format_Numb( "%4x"));

var v_hex= (4.3282).format_hex();

Хотя я что-то тестировал, в коде может быть много ошибок. Так что это не готовый модуль, а просто идея и отправная точка для не-js-экспертов, таких как я. Код содержит много и мало модифицированных идей из множества сообщений stackoverflow; извините, я не могу сослаться на них всех, но спасибо всем экспертам.

10
задан Gaffi 26 July 2012 в 03:22
поделиться

2 ответа

Set textbox's MultiLine property to True and EnterKeyBehavior to True.

23
ответ дан 3 December 2019 в 17:21
поделиться

пробовали ли вы включить элемент управления отформатированным текстом для текста? Не уверен, насколько хорошо он работает с VBA, но в VB6 я бы использовал именно его.

0
ответ дан 3 December 2019 в 17:21
поделиться