[gnumeric] VLOOKUP/HLOOKUP: allow wildcard searches.
- From: Morten Welinder <mortenw src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnumeric] VLOOKUP/HLOOKUP: allow wildcard searches.
- Date: Sun, 18 Mar 2012 19:12:08 +0000 (UTC)
commit d1031d5ec03d18402c2f776b0e9be5042d5b86e5
Author: Morten Welinder <terra gnome org>
Date: Sun Mar 18 15:11:49 2012 -0400
VLOOKUP/HLOOKUP: allow wildcard searches.
NEWS | 1 +
plugins/fn-lookup/ChangeLog | 5 +++
plugins/fn-lookup/functions.c | 80 +++++++++++++++++++++++++----------------
3 files changed, 55 insertions(+), 31 deletions(-)
---
diff --git a/NEWS b/NEWS
index 01a03f5..43855bf 100644
--- a/NEWS
+++ b/NEWS
@@ -40,6 +40,7 @@ Morten:
* Lower per-cell memory usage.
* Fix INTERPOLATION crash. [#672154]
* Inhibit typing underline style in format dialog.
+ * Allow pattern matching for VLOOKUP/HLOOKUP. [#672319]
--------------------------------------------------------------------------
Gnumeric 1.11.2
diff --git a/plugins/fn-lookup/ChangeLog b/plugins/fn-lookup/ChangeLog
index cae33f8..e0019e4 100644
--- a/plugins/fn-lookup/ChangeLog
+++ b/plugins/fn-lookup/ChangeLog
@@ -1,3 +1,8 @@
+2012-03-18 Morten Welinder <terra gnome org>
+
+ * functions.c (gnumeric_vlookup, gnumeric_hlookup): Handle string
+ search with patterns. [#672319]
+
2012-03-02 Morten Welinder <terra gnome org>
* Release 1.11.2
diff --git a/plugins/fn-lookup/functions.c b/plugins/fn-lookup/functions.c
index 4c4e2fa..e0af337 100644
--- a/plugins/fn-lookup/functions.c
+++ b/plugins/fn-lookup/functions.c
@@ -437,6 +437,17 @@ find_compare_type_valid (GnmValue const *find, GnmValue const *val)
/* -------------------------------------------------------------------------- */
+static gboolean
+is_pattern_match (const char *s)
+{
+ while (*s) {
+ if (*s == '*' || *s == '?' || *s == '~')
+ return TRUE;
+ s++;
+ }
+ return FALSE;
+}
+
static int
calc_length (GnmValue const *data, GnmEvalPos const *ep, gboolean vertical)
{
@@ -949,26 +960,33 @@ static GnmFuncHelp const help_vlookup[] = {
static GnmValue *
gnumeric_vlookup (GnmFuncEvalInfo *ei, GnmValue const * const *args)
{
- int col_idx, index = -1;
- gboolean approx;
-
- col_idx = value_get_as_int (args[2]);
+ GnmValue const *find = args[0];
+ int col_idx = value_get_as_int (args[2]);
+ gboolean approx = args[3] ? value_get_as_checked_bool (args[3]) : TRUE;
+ gboolean as_index = args[4] && value_get_as_checked_bool (args[4]);
+ int index;
+ gboolean is_string_match;
- if (!find_type_valid (args[0]))
+ if (!find_type_valid (find))
return value_new_error_NA (ei->pos);
if (col_idx <= 0)
return value_new_error_VALUE (ei->pos);
if (col_idx > value_area_get_width (args[1], ei->pos))
return value_new_error_REF (ei->pos);
- approx = args[3] ? value_get_as_checked_bool (args[3]) : TRUE;
- index = approx
- ? find_index_bisection (ei, args[0], args[1], 1, TRUE)
- : find_index_linear (ei, args[0], args[1], TRUE);
+ is_string_match = (!approx &&
+ VALUE_IS_STRING (find) &&
+ is_pattern_match (value_peek_string (find)));
+
+ index = is_string_match
+ ? find_index_bisection (ei, find, args[1], 0, TRUE)
+ : (approx
+ ? find_index_bisection (ei, find, args[1], 1, TRUE)
+ : find_index_linear (ei, find, args[1], TRUE));
if (index == LOOKUP_DATA_ERROR)
return value_new_error_VALUE (ei->pos); /* 3D */
- if (args[4] != NULL && value_get_as_checked_bool (args[4]))
+ if (as_index)
return value_new_int (index);
if (index >= 0) {
@@ -1010,26 +1028,33 @@ static GnmFuncHelp const help_hlookup[] = {
static GnmValue *
gnumeric_hlookup (GnmFuncEvalInfo *ei, GnmValue const * const *args)
{
- int row_idx, index = -1;
- gboolean approx;
-
- row_idx = value_get_as_int (args[2]);
+ GnmValue const *find = args[0];
+ int row_idx = value_get_as_int (args[2]);
+ gboolean approx = args[3] ? value_get_as_checked_bool (args[3]) : TRUE;
+ gboolean as_index = args[4] && value_get_as_checked_bool (args[4]);
+ int index;
+ gboolean is_string_match;
- if (!find_type_valid (args[0]))
+ if (!find_type_valid (find))
return value_new_error_NA (ei->pos);
if (row_idx <= 0)
return value_new_error_VALUE (ei->pos);
if (row_idx > value_area_get_height (args[1], ei->pos))
return value_new_error_REF (ei->pos);
- approx = args[3] ? value_get_as_checked_bool (args[3]) : TRUE;
- index = approx
- ? find_index_bisection (ei, args[0], args[1], 1, FALSE)
- : find_index_linear (ei, args[0], args[1], FALSE);
+ is_string_match = (!approx &&
+ VALUE_IS_STRING (find) &&
+ is_pattern_match (value_peek_string (find)));
+
+ index = is_string_match
+ ? find_index_bisection (ei, find, args[1], 0, FALSE)
+ : (approx
+ ? find_index_bisection (ei, find, args[1], 1, FALSE)
+ : find_index_linear (ei, find, args[1], FALSE));
if (index == LOOKUP_DATA_ERROR)
return value_new_error_VALUE (ei->pos); /* 3D */
- if (args[4] != NULL && value_get_as_checked_bool (args[4]))
+ if (as_index)
return value_new_int (index);
if (index >= 0) {
@@ -1169,7 +1194,7 @@ gnumeric_match (GnmFuncEvalInfo *ei, GnmValue const * const *args)
int height = value_area_get_height (args[1], ei->pos);
gboolean vertical;
GnmValue const *find = args[0];
- gboolean is_string_match = FALSE;
+ gboolean is_string_match;
if (!find_type_valid (find))
return value_new_error_NA (ei->pos);
@@ -1180,16 +1205,9 @@ gnumeric_match (GnmFuncEvalInfo *ei, GnmValue const * const *args)
type = VALUE_IS_EMPTY (args[2]) ? 1 : value_get_as_int (args[2]);
- if (type == 0 && VALUE_IS_STRING (find)) {
- const char *s = value_peek_string (find);
- while (*s) {
- if (*s == '*' || *s == '?' || *s == '~') {
- is_string_match = TRUE;
- break;
- }
- s++;
- }
- }
+ is_string_match = (type == 0 &&
+ VALUE_IS_STRING (find) &&
+ is_pattern_match (value_peek_string (find)));
if (type == 0 && !is_string_match)
index = find_index_linear (ei, find, args[1], vertical);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]