// ------------------------------------------------------------------------------------------------
  // 描述:
  // 设计: Skyline(2001.12.29)
  // 实现: Skyline
  // 修改:
  // ------------------------------------------------------------------------------------------------
  public JFunctionStub getFunctionByID(String ID, Object OwnerObject) {
    IFunction IF = null;
    JFunctionStub FS = null;
    String FT;
    try {
      for (int i = 0; i < FunctionList.size(); i++) {
        FS = (JFunctionStub) FunctionList.get(i);
        //        System.out.println(FS.FunctionID);
        FT = FS.FunctionID + "_";
        if (FS.FunctionID.equals(ID) || FT.equals(ID)) {
          if (FS.Function == null) {
            FS.FunctionClass = Class.forName(FS.ClassName);
            FS.Function = (IFunction) FS.FunctionClass.newInstance();
            FS.Function.InitFunction(FS);
          }
          /* else { // modify by liukun 找到了就直接返回吧 20100715
            return FS;
          }
          */
          //
          if (OwnerObject != null && OwnerObject instanceof Hashtable) {
            Hashtable OTable = (Hashtable) OwnerObject;
            JFunctionStub fs = (JFunctionStub) OTable.get(ID);
            if (fs == null) {
              fs = new JFunctionStub();
              fs.ClassName = FS.ClassName;
              fs.FunctionClass = FS.FunctionClass;
              fs.FunctionID = FS.FunctionID;
              OTable.put(ID, fs);
            }
            if (fs.Function == null) {
              fs.FunctionClass = Class.forName(FS.ClassName);
              fs.Function = (IFunction) FS.FunctionClass.newInstance();
              fs.Function.InitFunction(FS);
            }
            FS = fs;
          } else {
            /**
             * 如果不在用户列表中则需要重新初始化函数 不能直接用系统缓存因为系统缓存只在登录时初始 这样对于像BB类函数,缓冲坐标的行为就可能会出错(中间修改过行列) modified
             * by hufeng 2007.11.20
             */
            FS.Function = (IFunction) FS.FunctionClass.newInstance();
            FS.Function.InitFunction(FS);
          }

          return FS;
        }
      }
    } catch (Exception e) {
      e.printStackTrace();
    }
    return null;
  }
  /**
   * 分析并计算各报表函数 返回一个计算后的表达式
   *
   * @param f1string String
   * @param PO JParamObject
   * @param ConnObject Object
   * @param Scan IScanFunction
   * @param UserObject Object
   * @param OwnerObject Object
   * @return String
   * @throws Exception
   */
  public String ScanFunctionFromF1(
      String f1string,
      JParamObject PO,
      Object ConnObject,
      IScanFunction Scan,
      Object UserObject,
      Object OwnerObject)
      throws Exception {
    Stack SourceStack = new Stack();
    int i = 0, b = 0, f = 0;
    String sTmp1, sTmp2, FTag, FString, F1String;
    JFunctionStub FS = null;
    F1String = f1string;
    int itmp = 1;
    while (i < F1String.length()) {
      sTmp1 = F1String.substring(i, i + 1);
      // 如果等"("压栈
      if (sTmp1.equals("(")) {
        SourceStack.push(String.valueOf(i));
      }
      // 括号封闭
      if (sTmp1.equals(")")) {
        sTmp2 = (String) SourceStack.pop();
        b = Integer.valueOf(sTmp2).intValue();
        f = b - 1;
        // 找出函数的左边的开始位置
        while (f >= 0) {
          sTmp2 = F1String.substring(f, f + 1);
          if (FunctionTag.indexOf(sTmp2) != -1) {
            break;
          } else f--;
        }
        f++;
        FTag = F1String.substring(f, b);
        FString = F1String.substring(f, i + 1);
        /**
         * 将函数取TRIM,因为在函数两端可能存在空格,这样会导致函数计算不出来 如:KMJE(1001,JFFS) + KMJE(1002,JFFS) modified by
         * hufeng 2005.9.7
         */
        FTag = FTag.trim();
        FS = getFunctionByID(FTag, OwnerObject);
        //          if ( FS == null ) {
        //            System.out.println("找不到函数的实现类"+FTag);
        //            throw new Exception("找不到函数的实现类"+FTag);
        //          }
        if (PO != null && FS != null && Scan instanceof JCalculateZbRequestObject) {
          PO.SetValueByParamName("TMP_NUM", String.valueOf(itmp));
          itmp++;
        }
        FTag = (String) Scan.ScanReplace(FS, FString, PO, ConnObject, UserObject); // 第一条语句出处
        // add by fsz 2004.5.`14 如果没有错误,返回SQL
        if (FS != null) Text += FS.Function.getErrText();
        // end
        if (FTag != null) {
          F1String = F1String.substring(0, f) + FTag + F1String.substring(i + 1, F1String.length());
          // i从替换后听位置处开始处理
          i = f + FTag.length();
          continue;
        } else {
          i = f + FString.length();
          continue;
        }
      }
      i++;
    }
    if (SourceStack.size() != 0) {
      throw new Exception("公式定义错误,左右括号不匹配!");
    }
    Boolean boo = false;
    while (b < F1String.length()) {
      sTmp2 = F1String.substring(b, b + 1);
      if (sTmp2.equals(";")) {
        boo = true;
        b = 0;
        break;
      }
      b++;
    }
    if (boo == true) {
      throw new Exception("公式定义中不允许包含字符 ';' !");
    }

    return F1String;
  }