Skip to content

Commit 42fa2b2

Browse files
authored
Add new function search_sheet (#8)
- Update unit tests and docs for the function
1 parent 5b8eb2e commit 42fa2b2

File tree

6 files changed

+105
-0
lines changed

6 files changed

+105
-0
lines changed

excelize.py

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2054,6 +2054,51 @@ def remove_row(self, sheet: str, row: int) -> Optional[Exception]:
20542054
)
20552055
return None if err == "" else Exception(err)
20562056

2057+
def search_sheet(
2058+
self, sheet: str, value: str, *reg: bool
2059+
) -> Tuple[List[str], Optional[Exception]]:
2060+
"""
2061+
Get cell reference by given worksheet name, cell value, and regular
2062+
expression. The function doesn't support searching on the calculated
2063+
result, formatted numbers and conditional lookup currently. If it is a
2064+
merged cell, it will return the cell reference of the upper left cell of
2065+
the merged range reference.
2066+
2067+
Args:
2068+
sheet (str): The worksheet name
2069+
value (str): The cell value to search
2070+
*reg (bool): Specifies if search with regular expression
2071+
2072+
Returns:
2073+
Tuple[List[str], Optional[Exception]]: A tuple containing the
2074+
cell name and an exception if an error occurred, otherwise None.
2075+
2076+
Example:
2077+
An example of search the cell reference of the value of "100" on
2078+
Sheet1:
2079+
2080+
```python
2081+
result, err = f.search_sheet("Sheet1", "100")
2082+
```
2083+
2084+
An example of search the cell reference where the numerical value in
2085+
the range of "0-9" of Sheet1 is described:
2086+
2087+
```python
2088+
result, err = f.search_sheet("Sheet1", "[0-9]", True)
2089+
```
2090+
"""
2091+
lib.SearchSheet.restype = types_go._StringArrayErrorResult
2092+
res = lib.SearchSheet(
2093+
self.file_index,
2094+
sheet.encode(ENCODE),
2095+
value.encode(ENCODE),
2096+
reg[0] if reg else False,
2097+
)
2098+
arr = c_value_to_py(res, StringArrayErrorResult()).arr
2099+
err = res.Err.decode(ENCODE)
2100+
return arr if arr else [], None if err == "" else Exception(err)
2101+
20572102
def set_active_sheet(self, index: int) -> Optional[Exception]:
20582103
"""
20592104
Set the default active sheet of the workbook by a given index. Note that

main.go

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1773,6 +1773,31 @@ func SaveAs(idx int, name *C.char, opts *C.struct_Options) *C.char {
17731773
return C.CString(emptyString)
17741774
}
17751775

1776+
1777+
// SearchSheet provides a function to get cell reference by given worksheet name,
1778+
// cell value, and regular expression. The function doesn't support searching
1779+
// on the calculated result, formatted numbers and conditional lookup
1780+
// currently. If it is a merged cell, it will return the cell reference of the
1781+
// upper left cell of the merged range reference.
1782+
//
1783+
//export SearchSheet
1784+
func SearchSheet(idx int, sheet, value *C.char, reg bool) C.struct_StringArrayErrorResult {
1785+
f, ok := files.Load(idx)
1786+
if !ok {
1787+
return C.struct_StringArrayErrorResult{Err: C.CString(errFilePtr)}
1788+
}
1789+
result, err := f.(*excelize.File).SearchSheet(C.GoString(sheet), C.GoString(value), reg)
1790+
if err != nil {
1791+
return C.struct_StringArrayErrorResult{Err: C.CString(err.Error())}
1792+
}
1793+
cArray := C.malloc(C.size_t(len(result)) * C.size_t(unsafe.Sizeof(uintptr(0))))
1794+
cArrayPtr := (*[1 << 30]*C.char)(cArray)
1795+
for i, v := range result {
1796+
cArrayPtr[i] = C.CString(v)
1797+
}
1798+
return C.struct_StringArrayErrorResult{ArrLen: C.int(len(result)), Arr: (**C.char)(cArray), Err: C.CString(emptyString)}
1799+
}
1800+
17761801
// SetActiveSheet provides a function to set the default active sheet of the
17771802
// workbook by a given index. Note that the active index is different from the
17781803
// ID returned by function GetSheetMap(). It should be greater than or equal

test_excelize.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,22 @@ def test_style(self):
256256
self.assertEqual("100", val)
257257
self.assertIsNone(err)
258258

259+
result, err = f.search_sheet("Sheet1", "Hello")
260+
self.assertIsNone(err)
261+
self.assertEqual(result, ["A3", "A12"])
262+
263+
result, err = f.search_sheet("Sheet1", "H", True)
264+
self.assertIsNone(err)
265+
self.assertEqual(result, ["A3", "A12"])
266+
267+
result, err = f.search_sheet("Sheet1", "H", False)
268+
self.assertIsNone(err)
269+
self.assertEqual(result, [])
270+
271+
result, err = f.search_sheet("SheetN", "H", False)
272+
self.assertEqual(str(err), "sheet SheetN does not exist")
273+
self.assertEqual(result, [])
274+
259275
self.assertIsNone(f.duplicate_row("Sheet1", 20))
260276
self.assertIsNone(f.duplicate_row_to("Sheet1", 20, 20))
261277
self.assertIsNone(f.insert_cols("Sheet1", "C", 2))

types_c.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -709,6 +709,13 @@ struct BoolErrorResult
709709
char *err;
710710
};
711711

712+
struct StringArrayErrorResult
713+
{
714+
int ArrLen;
715+
char **Arr;
716+
char *Err;
717+
};
718+
712719
struct GetCellHyperLinkResult
713720
{
714721
bool link;

types_go.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -685,6 +685,12 @@ class _BoolErrorResult(Structure):
685685
("err", c_char_p),
686686
]
687687

688+
class _StringArrayErrorResult(Structure):
689+
_fields_ = [
690+
("ArrLen", c_int),
691+
("Arr", POINTER(POINTER(c_char))),
692+
("Err", c_char_p),
693+
]
688694

689695
class _CellNameToCoordinatesResult(Structure):
690696
_fields_ = [

types_py.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -767,3 +767,9 @@ class WorkbookProtectionOptions:
767767
password: str = ""
768768
lock_structure: bool = False
769769
lock_windows: bool = False
770+
771+
772+
@dataclass
773+
class StringArrayErrorResult:
774+
arr: Optional[List[str]] = None
775+
err: str = ""

0 commit comments

Comments
 (0)