/// <summary> /// /// </summary> /// <param name="record"></param> /// <param name="checkRange"></param> /// <returns></returns> internal override UnitComputeResult Compute(IRecord record, bool checkRange, bool recompute, bool computeInitExpressions) { UnitComputeResult result = new UnitComputeResult(); string fieldValue = fieldView.ValueFromCurrentRecord; switch (fieldView.StorageAttribute) { case StorageAttribute.NUMERIC: { NUM_TYPE fetchedValue = new NUM_TYPE(fieldValue); NUM_TYPE minimumValue = new NUM_TYPE(DisplayConvertor.Instance.toNum((string)minValue, new PIC(fieldView.Picture, StorageAttribute.NUMERIC, 0), 0)); if (NUM_TYPE.num_cmp(fetchedValue, minimumValue) < 0) { result.ErrorCode = UnitComputeErrorCode.LocateFailed; } } break; case StorageAttribute.UNICODE: case StorageAttribute.ALPHA: { //QCR # 444514 : Check whether given Incremental Locate String is in between min and max of fetched value. // Locate gets successful when fetched record is greater than or equal to search Incremental Locate String value. string minimumValue = minValue.ToString().PadRight(fieldView.Length, char.MinValue); string maximumValue = minValue.ToString().PadRight(fieldView.Length, char.MaxValue); if (String.Compare(fieldValue, (string)minimumValue, StringComparison.Ordinal) < 0) { result.ErrorCode = UnitComputeErrorCode.LocateFailed; } else if (String.Compare(fieldValue, (string)maximumValue, StringComparison.Ordinal) > 0) { result.ErrorCode = UnitComputeErrorCode.LocateFailed; } } break; } return(result); }
/// <summary> /// returns the array of indice for an item in the list by comparing the mgVal to the linked value or (-1) if none was /// found /// </summary> /// <param name = "mgVal">the internal value to look for </param> /// <param name = "isVectorValue">Denotes whether the value in mgVal should be treated as a vector (true) or not (false).</param> /// <param name = "isNull">true if the value to look for is null </param> /// <param name = "extraVals">Additional values, prepended to the searched values.</param> /// <param name="extraNums">Additional numeric values to be prepended to the searched values.</param> /// <param name = "splitCommaSeperatedVals">to split the val on comma or not </param> public int[] getIndexOf(string mgVal, bool isVectorValue, bool isNull, string[] extraVals, NUM_TYPE[] extraNums, bool splitCommaSeperatedVals) { int result = NOT_FOUND; String tmpMgVal; NUM_TYPE ctrlNumVal; String trimmedVal; String[] vals = null; NUM_TYPE[] nums = null; int offset = 0; int firstFitMatchIdx = NOT_FOUND; int firstFitMatchLength = -1; int minLength = -1; String compStr = ""; int[] indice = null; string[] values = null; if (isNull) { int i = 0; indice = new int[1] { NOT_FOUND }; for (i = 0; _nullFlags != null && i < _nullFlags.Length; i++) { if (_nullFlags[i]) { indice[0] = i; break; } } return(indice); } if (!isVectorValue) { //split the comma separated values; if (splitCommaSeperatedVals) { values = mgVal.Split(new char[] { ',' }); } else { values = new string[] { mgVal } }; } else { VectorType vector = new VectorType(mgVal); values = vector.GetCellValues(); } indice = new int[values.Length]; for (int iCtr = 0; iCtr < values.Length; iCtr++) { //Initialize result. result = NOT_FOUND; firstFitMatchIdx = NOT_FOUND; tmpMgVal = values[iCtr]; if (_isNumericType || extraNums != null) { try { ctrlNumVal = new NUM_TYPE(tmpMgVal); } catch (IndexOutOfRangeException) { indice = new int[1]; indice[0] = NOT_FOUND; return(indice); } trimmedVal = tmpMgVal; } else { ctrlNumVal = null; trimmedVal = StrUtil.rtrim(tmpMgVal); } // Run two passes. First one on extra values, second one on values belonging to this object for (int i = 0; i < 2 && result == NOT_FOUND; i++) { switch (i) { case 0: vals = extraVals; nums = extraNums; offset = 0; break; case 1: default: if (_isNumericType || nums != null) { offset = (nums == null ? 0 : nums.Length); } else { offset = (vals == null ? 0 : vals.Length); } vals = _linkVals; nums = _numVals; break; } if (vals != null) { for (int j = 0; j < vals.Length && result == NOT_FOUND; j++) { if (_isNumericType || nums != null) { if (NUM_TYPE.num_cmp(ctrlNumVal, nums[j]) == 0 || (Object)tmpMgVal == (Object)vals[j] || tmpMgVal.Equals(vals[j])) { // the numeric type is found exactly result = j + offset; break; } } else { if (vals[j].Equals(tmpMgVal) || trimmedVal.Length > 0 && StrUtil.rtrim(vals[j]).Equals(trimmedVal)) { result = j + offset; break; } //If Magic sent us a blank value, and such a value exists in the "non DC range" select it. //QCR # 751037 - search for blank values even in the linked values array of the data control if (trimmedVal.Length == 0 && StrUtil.rtrim(vals[j]).Length == 0) { result = j + offset; break; } // save the first fitting result // fixed bug#: 935015, the comparison will be according to the min length of the data & the options if (result == NOT_FOUND && trimmedVal.Length > 0) { minLength = Math.Min(trimmedVal.Length, vals[j].Length); compStr = trimmedVal.Substring(0, minLength); if (compStr.Length > 0 && vals[j].StartsWith(compStr)) { // if there is a min length match, check if it is the first fit match. // eg: if list has a,aaa,aaaaa and field value is 'aa' then first fit match is 'aaa'. // if list is a,aaaaa,aaa and field value is 'aa' then first fit match is 'aaaaa'. // if first fit not found, then closest match is used (eg- if field value is // 'aaaaaaaaa' in both the above list, closest match would be 'aaaaa'). if (minLength > firstFitMatchLength) { firstFitMatchIdx = j + offset; firstFitMatchLength = minLength; } } } } } } } if (result == NOT_FOUND) { result = firstFitMatchIdx; } //store indice found in integer array. indice[iCtr] = result; } return(indice); }
/// <returns> translation of this argument into Magic URL style (e.g. -Aalpha or -N17 etc.)</returns> protected internal void toURL(StringBuilder htmlArgs, bool makePrintable) { if (!skipArg()) { String argValue = null, rangeStr = null; StorageAttribute attribute = StorageAttribute.NONE; bool isNull = false; PIC pic = null; NUM_TYPE num1, num2; Expression.ReturnValue retVal; int compIdx = 0; // Get the value and attribute and set the "is null" flag according // to the argument type switch (_type) { case ConstInterface.ARG_TYPE_VALUE: isNull = _valueIsNull; attribute = _valueAttr; argValue = _val; break; case ConstInterface.ARG_TYPE_EXP: retVal = _exp.evaluate(2000); argValue = retVal.mgVal; if (argValue == null) { isNull = true; } else { attribute = retVal.type; } compIdx = _exp.getTask().getCompIdx(); break; case ConstInterface.ARG_TYPE_FIELD: if (_fld.isNull()) { isNull = true; } else { argValue = _fld.getValue(false); attribute = _fld.getType(); } compIdx = _fld.getTask().getCompIdx(); break; case ConstInterface.ARG_TYPE_SKIP: isNull = true; //#919535 If argument is skipped then pass NULL it will handled in server. break; } // Create the argument string if (isNull) { htmlArgs.Append(ConstInterface.REQ_ARG_NULL); } else { switch (attribute) { case StorageAttribute.NUMERIC: num1 = new NUM_TYPE(argValue); num2 = new NUM_TYPE(argValue); num1.round(0); if (NUM_TYPE.num_cmp(num1, num2) == 0) { pic = new PIC("" + UtilStrByteMode.lenB(argValue), StorageAttribute.ALPHA, compIdx); String numDispVal = num2.to_a(pic).Trim(); if (numDispVal.Length <= 9) { htmlArgs.Append(ConstInterface.REQ_ARG_NUMERIC + num2.to_a(pic).Trim()); } else { htmlArgs.Append(ConstInterface.REQ_ARG_DOUBLE + num2.to_double()); } } else { htmlArgs.Append(ConstInterface.REQ_ARG_DOUBLE + num2.to_double()); } break; case StorageAttribute.DATE: pic = new PIC(Manager.GetDefaultDateFormat(), attribute, compIdx); rangeStr = ""; htmlArgs.Append(ConstInterface.REQ_ARG_ALPHA); break; case StorageAttribute.TIME: pic = new PIC(Manager.GetDefaultTimeFormat(), attribute, compIdx); rangeStr = ""; htmlArgs.Append(ConstInterface.REQ_ARG_ALPHA); break; case StorageAttribute.ALPHA: // alpha strings are kept internally as Unicode, so fall through to unicode case... case StorageAttribute.UNICODE: pic = new PIC("" + UtilStrByteMode.lenB(argValue), attribute, compIdx); rangeStr = ""; /* TODO: Kaushal. this should be "-U". * "-U" is currently used for null value. */ htmlArgs.Append(ConstInterface.REQ_ARG_UNICODE); break; case StorageAttribute.BLOB: pic = new PIC("", attribute, compIdx); rangeStr = ""; char contentType = BlobType.getContentType(argValue); // ANSI blobs are later translated to Unicode if (contentType == BlobType.CONTENT_TYPE_UNICODE || contentType == BlobType.CONTENT_TYPE_ANSI) { htmlArgs.Append(ConstInterface.REQ_ARG_UNICODE); } else { htmlArgs.Append(ConstInterface.REQ_ARG_ALPHA); } break; case StorageAttribute.BLOB_VECTOR: pic = new PIC("", attribute, compIdx); rangeStr = ""; htmlArgs.Append(ConstInterface.REQ_ARG_ALPHA); //QCR 970794 appending eye catcher for vectors passed as arguments on hyperlink argValue = ConstInterface.MG_HYPER_ARGS + BlobType.removeBlobPrefix(argValue) + ConstInterface.MG_HYPER_ARGS; break; case StorageAttribute.BOOLEAN: pic = new PIC("5", attribute, compIdx); rangeStr = "TRUE,FALSE"; htmlArgs.Append(ConstInterface.REQ_ARG_LOGICAL); break; } if (attribute != StorageAttribute.NUMERIC) { string finalValue = StrUtil.rtrim(DisplayConvertor.Instance.mg2disp(argValue, rangeStr, pic, compIdx, false)); //QCR 970794 converting the url to a legal format htmlArgs.Append(makePrintable ? GUIManager.Instance.makeURLPrintable(finalValue) : finalValue); } } } }