24.02.2010, 19:05 | #1 |
Участник
|
Kashperuk Ivan: Casing and text search/comparison tutorial
Источник: http://kashperuk.blogspot.com/2010/0...omparison.html
============== I have recently received a question from one of my blog readers. He was asking about the possibility of doing case-sensitive search in AX. I would like to reply to that by creating a small tutorial on search in AX. It is definitely not going to cover all the scenarios, but will give beginners a basic understanding of their options. Download the tutorial xpo from my Skydrive The tutorial consists of 1 form with 3 tab pages. 1. Comparing two strings in AX is very simple: You can basically use the equality operator "==". As you can see from the tutorial, this is the case-insensitive operations, so "vanya" is equal to "Vanya". AX also supports case-sensitive comparison. Kernel function strCmp() compares two strings taking into account the casing of the symbols in the string. 2. Searching for a substring is a common operation in AX. For that you have a number of options, as usual: strScan() function ignores casing and allows you to specify from which position to search, and how many symbols. This is very basic, and a method like this is present in any programming language. TextBuffer.find() is a more advanced use of the search mechanism. First of all, it allows to ignore or take into account the casing in the source text. Similar to strScan, it allows to specify the start position for the search. What it also has is support for Regular Expressions, as well as the ability to, for example, paste the text to Windows clipboard. Lastly, there is the match() function. The main purpose of it is to find a match based on the specified pattern using regular expressions, but nothing prevents using it for a simple search operation. It has a rather limited output though. You only get a boolean value stating whether a match was found or not, while with the previous 2 methods you also get the position of the substring. Interesting An interesting discovery that I made when writing the tutorial was about the speed of the different search operations. I have included this into the tutorial, so you can go in and try it yourself on your specific setup. On my box, strScan() was the slowest operation of all, while TextBuffer, which I considered to be a very heavy class, was performing rather well. Of course, single operation time compared to database operations is very low, so you won't notice it in your daily work. But it is something to think about. 3. Finding a symbol in a string based on a specified set of symbols is also possible. You have 2 functions at your disposal for that: strFind and strNFind. The difference is that strNFind searches for any symbol NOT present in the provided set, compared to strFind. This is not an extensive list, so I would be interested in hearing which functions you use or what your results for performance comparison would be. Источник: http://kashperuk.blogspot.com/2010/0...omparison.html
__________________
Расскажите о новых и интересных блогах по Microsoft Dynamics, напишите личное сообщение администратору. |
|
25.02.2010, 08:44 | #2 |
Участник
|
Еще про SysCompare напиши. Кстати, ссылку на твой блог уже в книжки вставляют - в "геттинг стартед" есть, которую я недавно оборзел, есть
|
|
25.02.2010, 11:19 | #3 |
Участник
|
Этот Packt Publishing. Капец.
|
|
25.02.2010, 11:30 | #4 |
Участник
|
А про SysCompare я думал добавить, начал на него смотреть - полный трындец, а не код. mfp незачет
Да и вроде там нет public API для сравнения двух строк. Так что это решил упустить. |
|
25.02.2010, 12:26 | #5 |
Участник
|
\Classes\SysCompareText\run
правда имеет смысл только со много тросными строками. А в чем капец в СисКолмпейр? |
|
25.02.2010, 12:39 | #6 |
Участник
|
Цитата:
А, да, то есть АПИ таки есть. Капец - да просто туча кода и фиг поймешь че делает. нечитаемо. один из методов: X++: /// <summary> /// Fits records in the <c>ref</c> table so lines are only claimed one time. /// </summary> /// <remarks> /// After this operation, lines may be claimed by several records if the lines appear in several /// locations. In that case, one of the start positions and the length will be identical. /// </remarks> protected void fitRefs() { //Fit all the shorter ones //and the ones overlapping with same length TmpCompareText ref2; ; // // Example: // // #1 1 - 5 ; 2 - 6 -> This is longer than #2 and is kept // #2 3 - 4 ; 10 - 11 -> This is shadowed by #1 and is deleted // #3 7 - 7 ; 14 - 14 -> #3 and #4 are identical, and decision is deferred to refCleanup() // #4 7 - 7 ; 20 - 20 -> #3 and #4 are identical, and decision is deferred to refCleanup() // #5 10 - 15 ; 25 - 30 -> This is longer than #6 and is kept // #6 17 - 20 ; 29 - 32 -> This is partly shadowed by #2, and is trimmed to: 19 - 20 ; 31 - 32 // ref2.setTmpData(ref); while select ref order by Length desc, Text1Start { while select forupdate ref2 where ref2.Length <= ref.Length && ref2.RecId != ref.RecId && ((ref2.Text1Start >= ref.Text1Start && ref2.Text1Start <= ref.Text1End) || (ref2.Text1End >= ref.Text1Start && ref2.Text1End <= ref.Text1End) || (ref2.Text2Start >= ref.Text2Start && ref2.Text2Start <= ref.Text2End) || (ref2.Text2End >= ref.Text2Start && ref2.Text2End <= ref.Text2End)) { if ( ref2.Length < ref.Length || (ref2.Text1Start != ref.Text1Start && ref2.Text2Start != ref.Text2Start )) { if (ref2.Text1Start >= ref.Text1Start && ref2.Text1Start <= ref.Text1End) //Cut start of text1 in ref2 { ref2.Length = ref2.Length - (ref.Text1End + 1 - ref2.Text1Start); ref2.Text2Start = ref2.Text2Start + (ref.Text1End + 1 - ref2.Text1Start); ref2.Text1Start = ref.Text1End + 1; ref2.Text1End = ref2.Text1Start + ref2.Length - 1; ref2.Text2End = ref2.Text2Start + ref2.Length - 1; } if (ref2.Text1End >= ref.Text1Start && ref2.Text1End <= ref.Text1End) //Cut end of text1 in ref2 { ref2.Length = ref2.Length - (ref2.Text1End - (ref.Text1Start - 1)); ref2.Text2End = ref2.Text2End - (ref2.Text1End - (ref.Text1Start - 1)); ref2.Text1End = ref.Text1Start - 1; ref2.Text2Start = ref2.Text2End - (ref2.Length - 1); ref2.Text1Start = ref2.Text1End - (ref2.Length - 1); } if (ref2.Text2Start >= ref.Text2Start && ref2.Text2Start <= ref.Text2End) //Cut start of text2 in ref2 { ref2.Length = ref2.Length - (ref.Text2End + 1 - ref2.Text2Start); ref2.Text1Start = ref2.Text1Start + (ref.Text2End + 1 - ref2.Text2Start); ref2.Text2Start = ref.Text2End + 1; ref2.Text2End = ref2.Text2Start + ref2.Length - 1; ref2.Text1End = ref2.Text1Start + ref2.Length - 1; } if (ref2.Text2End >= ref.Text2Start && ref2.Text2End <= ref.Text2End) //Cut end of text2 in ref2 { ref2.Length = ref2.Length - (ref2.Text2End - (ref.Text2Start - 1)); ref2.Text1End = ref2.Text1End - (ref2.Text2End - (ref.Text2Start - 1)); ref2.Text2End = ref.Text2Start - 1; ref2.Text1Start = ref2.Text1End - (ref2.Length - 1); ref2.Text2Start = ref2.Text2End - (ref2.Length - 1); } if (ref2.Length <= 0) ref2.delete(); else ref2.update(); } } } } |
|
25.02.2010, 15:41 | #7 |
Участник
|
0. по моему единственная претензия к куску кода - то, что написано комментами можно было написать названиями методов.Так проде там довольно обычный код по устранению пересечений интервалов
1. ты попробуй сравнить многострочные строки типа X++: <at>'мама мыла раму' <at>'мама сверлила раму' Последний раз редактировалось belugin; 25.02.2010 в 15:43. |
|