public static String consultaBusquedaIds(
      String mol,
      String familia,
      String subfamilia,
      String subsubfamilia,
      String nombre,
      String nombresemi,
      String formula) {

    String ids = "";

    // Preparamos la busqueda por subestructura

    MolSearch s;
    MolHandler mh1;

    try {
      s = new MolSearch();
      s.setStereoCareChecking(false);
      mh1 = new MolHandler(mol);
      s.setQuery(mh1.getMolecule());

    } catch (chemaxon.formats.MolFormatException e) {
      System.out.println("Excepcion en la clase MolHandler (339): " + e.getMessage());
      return null;
    }

    String sql = "SELECT * FROM moleculas where estado>0 AND estado<5";

    if (nombre != null) if (!nombre.equals("")) sql += " AND nombre LIKE '" + nombre + "' ";

    if (nombresemi != null)
      if (!nombresemi.equals("")) sql += " AND nombresemisistematico LIKE '" + nombresemi + "' ";

    if (familia != null) if (!familia.equals("")) sql += " AND familia LIKE '" + familia + "' ";

    if (subfamilia != null)
      if (!subfamilia.equals("")) sql += " AND subfamilia LIKE '" + subfamilia + "' ";

    if (subsubfamilia != null)
      if (!subsubfamilia.equals("")) sql += " AND subsubfamilia LIKE '" + subsubfamilia + "' ";

    if (formula != null)
      if (!formula.equals("")) sql += " AND formulamolecular LIKE '" + formula + "' ";

    sql += " order by idmolecular";

    return sql;
  }
  /**
   * Este metodo nos permite hacer una busqueda por subestructura dentro de un conjunto reducido de
   * todos los registros de la base de datos.<br>
   * Este grupo de moleculas en el que se realizara la busqueda viene determinado por un parametro
   * del metodo.<br>
   * <br>
   *
   * @param mol Cadena donde esta guardado el codigo smiles de la subestructura que deberan contener
   *     todas aquellas moleculas que nos devuelva este metodo.
   * @param resultados Array unidimensional con los ids de aquellos registros de la base de datos
   *     entre los que se realizara la busqueda.
   * @param familia Familia a la que deben pertencer los compuestos a buscar.
   * @param subfamilia Subfamilia(o grupo) a la que deben pertencer los compuestos a buscar.
   * @param subsubfamilia Subsubfamilia(o tipo) a la que deben pertencer los compuestos a buscar.
   * @return Object[][] Array bidimensional con la informacion correspondiente a cada uno de los
   *     compuestos que cumplen las condiciones de busqueda, contiene el identificador, el smiles,
   *     el jme y el jmeDesplazamiento. Donde IdMoleculaX, idMoleculaY e idMoleculaZ estaran
   *     contenidos en el array resultados
   */
  public static Object[][] rebusqueda(
      String mol,
      int[] resultados,
      String familia,
      String subfamilia,
      String subsubfamilia,
      String nombre,
      String nombresemi,
      String formula) {

    Object res[][] = null;
    String ids = "";
    String smiles = "";
    String jme = "";
    String jmedes = "";
    String jmenum = "";

    // Preparamos la busqueda por subestructura

    MolSearch s;
    MolHandler mh1;

    try {
      s = new MolSearch();
      s.setStereoCareChecking(false);
      mh1 = new MolHandler(mol);
      s.setQuery(mh1.getMolecule());

    } catch (chemaxon.formats.MolFormatException e) {
      System.out.println("Excepcion en la clase MolHandler (413): " + e.getMessage());
      return null;
    }

    // Construimos la sentencia sql

    String sql =
        "SELECT idMolecular,smiles,jme,jmeDesplazamiento,jmeNumeracion FROM moleculas WHERE estado>0 AND estado<5 ";

    if (!nombre.equals("") && (nombre != null)) sql += " AND nombre LIKE '" + nombre + "' ";

    if (!nombresemi.equals("") && (nombresemi != null))
      sql += " AND nombresemisistematico LIKE '" + nombresemi + "' ";

    if (!familia.equals("") && (familia != null)) sql += " AND familia LIKE '" + familia + "' ";

    if (!subfamilia.equals("") && (subfamilia != null))
      sql += " AND subfamilia LIKE '" + subfamilia + "' ";

    if (!subsubfamilia.equals("") && (subsubfamilia != null))
      sql += " AND subsubfamilia LIKE '" + subsubfamilia + "' ";

    if (!formula.equals("") && (formula != null))
      sql += " AND formulamolecular LIKE '" + formula + "' ";

    sql += "AND ( ";

    for (int i = 0; i < resultados.length; i++) {
      if (i == (resultados.length) - 1) sql += "idMolecular=" + resultados[i];
      else sql += "idMolecular=" + resultados[i] + " OR ";
    }
    sql += ") order by idmolecular";
    // Nos conectamos con la base de datos y ejecutamos la sentencia sql

    Connection con = null;
    Statement stmt = null;
    ResultSet rs = null;

    try {
      con = Conexion2.conectar();
      stmt = con.createStatement();
      rs = stmt.executeQuery(sql);

      // Recorremos las filas que nos resultan de ejecutar la sentencia sql

      while (rs.next()) {
        // Recojemos datos
        int id = rs.getInt(1);
        String micodigo = rs.getString(2);
        String mijme = rs.getString(3);
        String mijmedes = rs.getString(4);
        String mijmenum = rs.getString(5);
        // Determinamos si es una subestructura o no

        MolHandler mh2 = null;
        boolean subestructura = false;
        try {

          mh2 = new MolHandler(micodigo);
          s.setTarget(mh2.getMolecule());

          subestructura = s.isMatching();

        } catch (chemaxon.formats.MolFormatException e) {
          System.out.println("Excepcion en la clase MolHandler (480): " + e.getMessage());
          return null;
        } catch (chemaxon.sss.search.SearchException e) {
          System.out.println("Excepcion en el metodo isMatching:" + e.getMessage());
          return null;
        }

        // En caso de que lo sea guardamos los datos necesarios

        if (subestructura) {
          ids += id + "*";
          smiles += micodigo + "*";
          jme += mijme + "*";
          jmedes += mijmedes + "*";
          jmenum += mijmenum + "*";
        }
      }
      StringTokenizer resultado1 = new StringTokenizer(ids, "*");
      StringTokenizer resultado2 = new StringTokenizer(smiles, "*");
      StringTokenizer resultado3 = new StringTokenizer(jme, "*");
      StringTokenizer resultado4 = new StringTokenizer(jmedes, "*");
      StringTokenizer resultado5 = new StringTokenizer(jmenum, "*");

      int registros = resultado1.countTokens();
      res = new Object[registros][5];

      int indice = 0;
      while (resultado1.hasMoreElements()) {
        res[indice][0] = resultado1.nextToken();
        res[indice][1] = resultado2.nextToken();
        res[indice][2] = resultado3.nextToken();
        res[indice][3] = resultado4.nextToken();
        res[indice][4] = resultado5.nextToken();
        indice++;
      }

      rs.close();
      stmt.close();
      Conexion2.desconectar(con);

    } catch (java.sql.SQLException e) {
      System.out.println("Excepcion al realizar la busqueda: " + e.getMessage());
      return null;
    } catch (java.lang.ClassNotFoundException e) {
      System.out.println("Excepcion al realizar la busqueda: " + e.getMessage());
      return null;
    }

    return res;
  }
  /**
   * Este metodo es igual que el de arriba pero solo retorna los idMoleculares reduciendo el tiempo
   * de busqueda
   *
   * <p>Este metodo permitira realizar una busqueda por subestructura molecular dentro de todos los
   * registros de la base de datos.<br>
   * <br>
   *
   * @param mol Cadena donde esta guardado el codigo smiles de la subestructura que deberan contener
   *     todas aquellas moleculas que nos devuelva este metodo.
   * @param familia Familia a la que deben pertencer los compuestos a buscar.
   * @param subfamilia Subfamilia(o grupo) a la que deben pertencer los compuestos a buscar.
   * @param subsubfamilia Subsubfamilia(o tipo) a la que deben pertencer los compuestos a buscar.
   * @return Object[][] Array bidimensional con la informacion correspondiente a cada uno de los
   *     compuestos que cumplen las condiciones de busqueda, contiene el identificador, el smiles,
   *     el jme y el jmeDesplazamiento. r>
   */
  public static Object[][] busquedaIds(
      String mol,
      String familia,
      String subfamilia,
      String subsubfamilia,
      String nombre,
      String nombresemi,
      String formula) {

    Object[][] res = null;
    String ids = "";

    // Preparamos la busqueda por subestructura

    MolSearch s;
    MolHandler mh1;

    try {
      s = new MolSearch();
      s.setStereoCareChecking(false);
      mh1 = new MolHandler(mol);
      s.setQuery(mh1.getMolecule());

    } catch (chemaxon.formats.MolFormatException e) {
      System.out.println("Excepcion en la clase MolHandler (214): " + e.getMessage());
      return null;
    }

    String sql = "SELECT idMolecular,smiles FROM moleculas where estado>0 AND estado<5";

    if (nombre != null) if (!nombre.equals("")) sql += " AND nombre LIKE '" + nombre + "' ";

    if (nombresemi != null)
      if (!nombresemi.equals("")) sql += " AND nombresemisistematico LIKE '" + nombresemi + "' ";

    if (familia != null) if (!familia.equals("")) sql += " AND familia LIKE '" + familia + "' ";

    if (subfamilia != null)
      if (!subfamilia.equals("")) sql += " AND subfamilia LIKE '" + subfamilia + "' ";

    if (subsubfamilia != null)
      if (!subsubfamilia.equals("")) sql += " AND subsubfamilia LIKE '" + subsubfamilia + "' ";

    if (formula != null)
      if (!formula.equals("")) sql += " AND formulamolecular LIKE '" + formula + "' ";

    sql += " order by idmolecular";

    // Nos conectamos con la base de datos y ejecutamos la sentencia sql

    Connection con = null;
    Statement stmt = null;
    ResultSet rs = null;

    try {

      con = Conexion2.conectar();
      stmt = con.createStatement();
      rs = stmt.executeQuery(sql);

      // Recorremos las filas que nos resultan de ejecutar la sentencia sql

      while (rs.next()) {
        // Recogemos datos
        int id = rs.getInt(1);
        String micodigo = rs.getString(2);
        // Determinamos si es una subestructura o no
        MolHandler mh2;
        boolean subestructura = false;
        try {
          mh2 = new MolHandler(micodigo);
          s.setTarget(mh2.getMolecule());
          subestructura = s.isMatching();

        } catch (chemaxon.formats.MolFormatException e) {
          System.out.println("Excepcion en la clase MolHandler (276): " + e.getMessage());
          e.printStackTrace(System.out);
          return null;
        } catch (chemaxon.sss.search.SearchException e) {
          System.out.println("Excepcion en el metodo isMatching:" + e.getMessage());
          return null;
        }

        // En caso de que lo sea guardamos los datos necesarios

        if (subestructura) {
          ids += id + "*";
        }
      }

      StringTokenizer resultado1 = new StringTokenizer(ids, "*");

      int registros = resultado1.countTokens();

      res = new Object[registros][2];

      int indice = 0;
      while (resultado1.hasMoreElements()) {
        res[indice][0] = resultado1.nextToken();
        indice++;
      }

      rs.close();
      stmt.close();
      Conexion2.desconectar(con);

    } catch (java.sql.SQLException e) {
      System.out.println("Excepcion al realizar la busqueda: " + e.getMessage());
      return null;
    } catch (java.lang.ClassNotFoundException e) {
      System.out.println("Excepcion al realizar la busqueda: " + e.getMessage());
      return null;
    }

    return res;
  }