xlwings-utils 25.0.6.post5__py3-none-any.whl → 25.0.7__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of xlwings-utils might be problematic. Click here for more details.
- xlwings_utils/xlwings_utils.py +57 -120
- {xlwings_utils-25.0.6.post5.dist-info → xlwings_utils-25.0.7.dist-info}/METADATA +20 -12
- xlwings_utils-25.0.7.dist-info/RECORD +6 -0
- xlwings_utils-25.0.6.post5.dist-info/RECORD +0 -6
- {xlwings_utils-25.0.6.post5.dist-info → xlwings_utils-25.0.7.dist-info}/WHEEL +0 -0
- {xlwings_utils-25.0.6.post5.dist-info → xlwings_utils-25.0.7.dist-info}/top_level.txt +0 -0
xlwings_utils/xlwings_utils.py
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
# /_/\_\|_| \_/\_/ |_||_| |_| \__, ||___/ _____ \__,_| \__||_||_||___/
|
|
6
6
|
# |___/ |_____|
|
|
7
7
|
|
|
8
|
-
__version__ = "25.0.
|
|
8
|
+
__version__ = "25.0.7"
|
|
9
9
|
|
|
10
10
|
|
|
11
11
|
import dropbox
|
|
@@ -20,7 +20,6 @@ Pythonista = sys.platform == "ios"
|
|
|
20
20
|
try:
|
|
21
21
|
import xlwings
|
|
22
22
|
|
|
23
|
-
xlwings = True
|
|
24
23
|
except ImportError:
|
|
25
24
|
xlwings = False
|
|
26
25
|
|
|
@@ -268,6 +267,7 @@ def read_local(path):
|
|
|
268
267
|
contents = f.read()
|
|
269
268
|
return contents
|
|
270
269
|
|
|
270
|
+
|
|
271
271
|
class block:
|
|
272
272
|
"""
|
|
273
273
|
block is 2 dimensional data structure with 1 as lowest index (like xlwings range)
|
|
@@ -291,9 +291,7 @@ class block:
|
|
|
291
291
|
self.number_of_columns = number_of_columns
|
|
292
292
|
|
|
293
293
|
@classmethod
|
|
294
|
-
def from_value(
|
|
295
|
-
cls, value, column_like=False, number_of_rows=missing, number_of_columns=missing
|
|
296
|
-
):
|
|
294
|
+
def from_value(cls, value, column_like=False):
|
|
297
295
|
"""
|
|
298
296
|
makes a block from a given value
|
|
299
297
|
|
|
@@ -331,14 +329,10 @@ class block:
|
|
|
331
329
|
if item and not (isinstance(item, float) and math.isnan(item)):
|
|
332
330
|
bl.dict[row, column] = item
|
|
333
331
|
bl._number_of_columns = max(bl.number_of_columns, column)
|
|
334
|
-
if number_of_rows is not missing:
|
|
335
|
-
bl.number_of_rows = number_of_rows
|
|
336
|
-
if number_of_columns is not missing:
|
|
337
|
-
bl.number_of_columns = number_of_columns
|
|
338
332
|
return bl
|
|
339
333
|
|
|
340
334
|
@classmethod
|
|
341
|
-
def from_range(cls, rng
|
|
335
|
+
def from_range(cls, rng):
|
|
342
336
|
"""
|
|
343
337
|
makes a block from a given range
|
|
344
338
|
|
|
@@ -358,16 +352,11 @@ class block:
|
|
|
358
352
|
block : block
|
|
359
353
|
"""
|
|
360
354
|
number_of_rows, number_of_columns = rng.shape
|
|
361
|
-
bl = cls.from_value(
|
|
362
|
-
rng.value,
|
|
363
|
-
column_like=(number_of_columns == 1),
|
|
364
|
-
number_of_rows=number_of_rows,
|
|
365
|
-
number_of_columns=number_of_columns,
|
|
366
|
-
)
|
|
355
|
+
bl = cls.from_value(rng.value, column_like=(number_of_columns == 1))
|
|
367
356
|
return bl
|
|
368
357
|
|
|
369
358
|
@classmethod
|
|
370
|
-
def from_xlrd_sheet(cls, sheet
|
|
359
|
+
def from_xlrd_sheet(cls, sheet):
|
|
371
360
|
"""
|
|
372
361
|
makes a block from a xlrd sheet
|
|
373
362
|
|
|
@@ -386,25 +375,16 @@ class block:
|
|
|
386
375
|
-------
|
|
387
376
|
block : block
|
|
388
377
|
"""
|
|
389
|
-
v = [
|
|
390
|
-
|
|
391
|
-
for row_idx in range(0, sheet.nrows)
|
|
392
|
-
]
|
|
393
|
-
return cls.from_value(
|
|
394
|
-
v, number_of_rows=number_of_rows, number_of_columns=number_of_columns
|
|
395
|
-
)
|
|
378
|
+
v = [sheet.row_values(row_idx)[0 : sheet.ncols] for row_idx in range(0, sheet.nrows)]
|
|
379
|
+
return cls.from_value(v)
|
|
396
380
|
|
|
397
381
|
@classmethod
|
|
398
|
-
def from_openpyxl_sheet(
|
|
399
|
-
cls, sheet, number_of_rows=missing, number_of_columns=missing
|
|
400
|
-
):
|
|
382
|
+
def from_openpyxl_sheet(cls, sheet):
|
|
401
383
|
v = [[cell.value for cell in row] for row in sheet.iter_rows()]
|
|
402
|
-
return cls.from_value(
|
|
403
|
-
v, number_of_rows=number_of_rows, number_of_columns=number_of_columns
|
|
404
|
-
)
|
|
384
|
+
return cls.from_value(v)
|
|
405
385
|
|
|
406
386
|
@classmethod
|
|
407
|
-
def from_file(cls, filename
|
|
387
|
+
def from_file(cls, filename):
|
|
408
388
|
"""
|
|
409
389
|
makes a block from a file
|
|
410
390
|
|
|
@@ -425,12 +405,10 @@ class block:
|
|
|
425
405
|
"""
|
|
426
406
|
with open(filename, "r") as f:
|
|
427
407
|
v = [[line if line else missing] for line in f.read().splitlines()]
|
|
428
|
-
return cls.from_value(
|
|
429
|
-
v, number_of_rows=number_of_rows, number_of_columns=number_of_columns
|
|
430
|
-
)
|
|
408
|
+
return cls.from_value(v)
|
|
431
409
|
|
|
432
410
|
@classmethod
|
|
433
|
-
def from_dataframe(cls, df
|
|
411
|
+
def from_dataframe(cls, df):
|
|
434
412
|
"""
|
|
435
413
|
makes a block from a given dataframe
|
|
436
414
|
|
|
@@ -450,9 +428,7 @@ class block:
|
|
|
450
428
|
block : block
|
|
451
429
|
"""
|
|
452
430
|
v = df.values.tolist()
|
|
453
|
-
return cls.from_value(
|
|
454
|
-
v, number_of_rows=number_of_rows, number_of_columns=number_of_columns
|
|
455
|
-
)
|
|
431
|
+
return cls.from_value(v)
|
|
456
432
|
|
|
457
433
|
def to_openpyxl_sheet(self, sheet):
|
|
458
434
|
"""
|
|
@@ -476,38 +452,50 @@ class block:
|
|
|
476
452
|
for row in self.value:
|
|
477
453
|
sheet.append(row)
|
|
478
454
|
|
|
455
|
+
def reshape(self, number_of_rows=missing, number_of_columns=missing):
|
|
456
|
+
"""
|
|
457
|
+
makes a new block with given dimensions
|
|
458
|
+
|
|
459
|
+
Parameters
|
|
460
|
+
----------
|
|
461
|
+
number_of_rows : int
|
|
462
|
+
if given, expand or shrink to the given number of rows
|
|
463
|
+
|
|
464
|
+
number_of_columns : int
|
|
465
|
+
if given, expand or shrink to the given number of columns
|
|
466
|
+
|
|
467
|
+
Returns
|
|
468
|
+
-------
|
|
469
|
+
block : block
|
|
470
|
+
"""
|
|
471
|
+
if number_of_rows is missing:
|
|
472
|
+
number_of_rows = self.number_of_rows
|
|
473
|
+
if number_of_columns is missing:
|
|
474
|
+
number_of_columns = self.number_of_columns
|
|
475
|
+
bl = block(number_of_rows=number_of_rows, number_of_columns=number_of_columns)
|
|
476
|
+
for (row, column), value in self.dict.items():
|
|
477
|
+
if row <= number_of_columns and column <= number_of_columns:
|
|
478
|
+
bl.dict[row, column] = value
|
|
479
|
+
return bl
|
|
480
|
+
|
|
479
481
|
@property
|
|
480
482
|
def value(self):
|
|
481
|
-
return [
|
|
482
|
-
[
|
|
483
|
-
self.dict.get((row, column))
|
|
484
|
-
for column in range(1, self.number_of_columns + 1)
|
|
485
|
-
]
|
|
486
|
-
for row in range(1, self.number_of_rows + 1)
|
|
487
|
-
]
|
|
483
|
+
return [[self.dict.get((row, column)) for column in range(1, self.number_of_columns + 1)] for row in range(1, self.number_of_rows + 1)]
|
|
488
484
|
|
|
489
485
|
def __setitem__(self, row_column, value):
|
|
490
486
|
row, column = row_column
|
|
491
487
|
if row < 1 or row > self.number_of_rows:
|
|
492
|
-
raise IndexError(
|
|
493
|
-
f"row must be between 1 and {self.number_of_rows} not {row}"
|
|
494
|
-
)
|
|
488
|
+
raise IndexError(f"row must be between 1 and {self.number_of_rows} not {row}")
|
|
495
489
|
if column < 1 or column > self.number_of_columns:
|
|
496
|
-
raise IndexError(
|
|
497
|
-
f"column must be between 1 and {self.number_of_columns} not {column}"
|
|
498
|
-
)
|
|
490
|
+
raise IndexError(f"column must be between 1 and {self.number_of_columns} not {column}")
|
|
499
491
|
self.dict[row, column] = value
|
|
500
492
|
|
|
501
493
|
def __getitem__(self, row_column):
|
|
502
494
|
row, column = row_column
|
|
503
495
|
if row < 1 or row > self.number_of_rows:
|
|
504
|
-
raise IndexError(
|
|
505
|
-
f"row must be between 1 and {self.number_of_rows} not {row}"
|
|
506
|
-
)
|
|
496
|
+
raise IndexError(f"row must be between 1 and {self.number_of_rows} not {row}")
|
|
507
497
|
if column < 1 or column > self.number_of_columns:
|
|
508
|
-
raise IndexError(
|
|
509
|
-
f"column must be between 1 and {self.number_of_columns} not {column}"
|
|
510
|
-
)
|
|
498
|
+
raise IndexError(f"column must be between 1 and {self.number_of_columns} not {column}")
|
|
511
499
|
return self.dict.get((row, column))
|
|
512
500
|
|
|
513
501
|
def minimized(self):
|
|
@@ -517,11 +505,7 @@ class block:
|
|
|
517
505
|
minimized block : block
|
|
518
506
|
uses highest_used_row_number and highest_used_column_number to minimize the block
|
|
519
507
|
"""
|
|
520
|
-
return
|
|
521
|
-
self,
|
|
522
|
-
number_of_rows=self.highest_used_row_number,
|
|
523
|
-
number_of_columns=self.highest_used_column_number,
|
|
524
|
-
)
|
|
508
|
+
return self.reshape(number_of_rows=self.highest_used_row_number, number_of_columns=self.highest_used_column_number)
|
|
525
509
|
|
|
526
510
|
@property
|
|
527
511
|
def number_of_rows(self):
|
|
@@ -576,9 +560,7 @@ class block:
|
|
|
576
560
|
if column < 1:
|
|
577
561
|
raise ValueError(f"{name}={column} < 1")
|
|
578
562
|
if column > self.number_of_columns:
|
|
579
|
-
raise ValueError(
|
|
580
|
-
f"{name}={column} > number_of_columns={self.number_of_columns}"
|
|
581
|
-
)
|
|
563
|
+
raise ValueError(f"{name}={column} > number_of_columns={self.number_of_columns}")
|
|
582
564
|
|
|
583
565
|
def transpose(self):
|
|
584
566
|
"""
|
|
@@ -588,23 +570,12 @@ class block:
|
|
|
588
570
|
-------
|
|
589
571
|
transposed block : block
|
|
590
572
|
"""
|
|
591
|
-
bl = block(
|
|
592
|
-
number_of_rows=self.number_of_columns, number_of_columns=self.number_of_rows
|
|
593
|
-
)
|
|
573
|
+
bl = block(number_of_rows=self.number_of_columns, number_of_columns=self.number_of_rows)
|
|
594
574
|
for (row, column), value in self.dict.items():
|
|
595
575
|
bl[column, row] = value
|
|
596
576
|
return bl
|
|
597
577
|
|
|
598
|
-
def vlookup(
|
|
599
|
-
self,
|
|
600
|
-
s,
|
|
601
|
-
*,
|
|
602
|
-
row_from=1,
|
|
603
|
-
row_to=missing,
|
|
604
|
-
column1=1,
|
|
605
|
-
column2=missing,
|
|
606
|
-
default=missing,
|
|
607
|
-
):
|
|
578
|
+
def vlookup(self, s, *, row_from=1, row_to=missing, column1=1, column2=missing, default=missing):
|
|
608
579
|
"""
|
|
609
580
|
searches in column1 for row between row_from and row_to for s and returns the value found at (that row, column2)
|
|
610
581
|
|
|
@@ -645,9 +616,7 @@ class block:
|
|
|
645
616
|
if column2 is missing:
|
|
646
617
|
column2 = column1 + 1
|
|
647
618
|
self._check_column(column2, "column2")
|
|
648
|
-
row = self.lookup_row(
|
|
649
|
-
s, row_from=row_from, row_to=row_to, column1=column1, default=-1
|
|
650
|
-
)
|
|
619
|
+
row = self.lookup_row(s, row_from=row_from, row_to=row_to, column1=column1, default=-1)
|
|
651
620
|
if row == -1:
|
|
652
621
|
if default is missing:
|
|
653
622
|
raise ValueError(f"{s} not found]")
|
|
@@ -712,16 +681,7 @@ class block:
|
|
|
712
681
|
else:
|
|
713
682
|
return default
|
|
714
683
|
|
|
715
|
-
def hlookup(
|
|
716
|
-
self,
|
|
717
|
-
s,
|
|
718
|
-
*,
|
|
719
|
-
column_from=1,
|
|
720
|
-
column_to=missing,
|
|
721
|
-
row1=1,
|
|
722
|
-
row2=missing,
|
|
723
|
-
default=missing,
|
|
724
|
-
):
|
|
684
|
+
def hlookup(self, s, *, column_from=1, column_to=missing, row1=1, row2=missing, default=missing):
|
|
725
685
|
"""
|
|
726
686
|
searches in row1 for column between column_from and column_to for s and returns the value found at (that column, row2)
|
|
727
687
|
|
|
@@ -762,9 +722,7 @@ class block:
|
|
|
762
722
|
if row2 is missing:
|
|
763
723
|
row2 = row1 + 1
|
|
764
724
|
self._check_row(row2, "row2")
|
|
765
|
-
column = self.lookup_column(
|
|
766
|
-
s, column_from=column_from, column_to=column_to, row1=row1, default=-1
|
|
767
|
-
)
|
|
725
|
+
column = self.lookup_column(s, column_from=column_from, column_to=column_to, row1=row1, default=-1)
|
|
768
726
|
if column == -1:
|
|
769
727
|
if default is missing:
|
|
770
728
|
raise ValueError(f"{s} not found")
|
|
@@ -773,9 +731,7 @@ class block:
|
|
|
773
731
|
else:
|
|
774
732
|
return self[row2, column]
|
|
775
733
|
|
|
776
|
-
def lookup_column(
|
|
777
|
-
self, s, *, column_from=1, column_to=missing, row1=1, default=missing
|
|
778
|
-
):
|
|
734
|
+
def lookup_column(self, s, *, column_from=1, column_to=missing, row1=1, default=missing):
|
|
779
735
|
"""
|
|
780
736
|
searches in row1 for column between column_from and column_to for s and returns that column number
|
|
781
737
|
|
|
@@ -825,16 +781,7 @@ class block:
|
|
|
825
781
|
else:
|
|
826
782
|
return default
|
|
827
783
|
|
|
828
|
-
def lookup(
|
|
829
|
-
self,
|
|
830
|
-
s,
|
|
831
|
-
*,
|
|
832
|
-
row_from=1,
|
|
833
|
-
row_to=missing,
|
|
834
|
-
column1=1,
|
|
835
|
-
column2=missing,
|
|
836
|
-
default=missing,
|
|
837
|
-
):
|
|
784
|
+
def lookup(self, s, *, row_from=1, row_to=missing, column1=1, column2=missing, default=missing):
|
|
838
785
|
"""
|
|
839
786
|
searches in column1 for row between row_from and row_to for s and returns the value found at (that row, column2)
|
|
840
787
|
|
|
@@ -876,14 +823,7 @@ class block:
|
|
|
876
823
|
----
|
|
877
824
|
This is exactly the same as vlookup.
|
|
878
825
|
"""
|
|
879
|
-
return self.vlookup(
|
|
880
|
-
s,
|
|
881
|
-
row_from=row_from,
|
|
882
|
-
row_to=row_to,
|
|
883
|
-
column1=column1,
|
|
884
|
-
column2=column2,
|
|
885
|
-
default=default,
|
|
886
|
-
)
|
|
826
|
+
return self.vlookup(s, row_from=row_from, row_to=row_to, column1=column1, column2=column2, default=default)
|
|
887
827
|
|
|
888
828
|
def decode_to_files(self):
|
|
889
829
|
"""
|
|
@@ -894,11 +834,7 @@ class block:
|
|
|
894
834
|
row = 1
|
|
895
835
|
bl = self.minimized()
|
|
896
836
|
while row <= self.number_of_rows:
|
|
897
|
-
if (
|
|
898
|
-
self[row, column]
|
|
899
|
-
and self[row, column].startswith("<file=")
|
|
900
|
-
and self[row, column].endswith(">")
|
|
901
|
-
):
|
|
837
|
+
if self[row, column] and self[row, column].startswith("<file=") and self[row, column].endswith(">"):
|
|
902
838
|
filename = self[row, column][6:-1]
|
|
903
839
|
collect = []
|
|
904
840
|
row += 1
|
|
@@ -943,6 +879,7 @@ class block:
|
|
|
943
879
|
row += 1
|
|
944
880
|
return bl.minimized()
|
|
945
881
|
|
|
882
|
+
|
|
946
883
|
class Capture:
|
|
947
884
|
"""
|
|
948
885
|
specifies how to capture stdout
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: xlwings_utils
|
|
3
|
-
Version: 25.0.
|
|
3
|
+
Version: 25.0.7
|
|
4
4
|
Summary: xlwings_utils
|
|
5
5
|
Author-email: Ruud van der Ham <rt.van.der.ham@gmail.com>
|
|
6
6
|
Project-URL: Homepage, https://github.com/salabim/xlwings_utils
|
|
@@ -87,14 +87,20 @@ xwu.write_dropbox('/downloads/file1.gif')
|
|
|
87
87
|
The module contains a useful 2-dimensional data structure: *block*.
|
|
88
88
|
This can be useful for manipulating a range without accessing it directly, which is expensive in terms of memory and execution time.
|
|
89
89
|
The advantage over an ordinary list of lists is that a block is index one-based, in line with range and addressing is done with a row, column tuple.
|
|
90
|
-
So, `my_block
|
|
90
|
+
So, `my_block[row, col]` is roughly equivalent to `lol[row-1][col-1]`
|
|
91
91
|
|
|
92
|
-
A block stores the values internally as a dictionary and will only convert these to a list of lists when using `block.value
|
|
92
|
+
A block stores the values internally as a dictionary and will only convert these to a list of lists when using `block.value`.
|
|
93
93
|
|
|
94
|
-
Converting
|
|
94
|
+
Converting of a range to a block can be done like
|
|
95
95
|
|
|
96
96
|
```
|
|
97
|
-
|
|
97
|
+
rng = book.sheets.active.range((5,7),(8,100))
|
|
98
|
+
my_block = xwu.block.from_range(rng
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
A value of a range (list of lists, list of scalars or scalar can be converted to a block with
|
|
102
|
+
```
|
|
103
|
+
my_block = xwu.block.from_value(rng.value)
|
|
98
104
|
```
|
|
99
105
|
The dimensions (number of rows and number of columns) are automatically set.
|
|
100
106
|
|
|
@@ -115,9 +121,10 @@ block = xwu.block(number_of_rows, number_columns)
|
|
|
115
121
|
The dimensions can be queried or redefined with `block.number_of_rows` and
|
|
116
122
|
`block.number_of_columns`.
|
|
117
123
|
|
|
118
|
-
|
|
124
|
+
It is also possible to get a copy of a block with different dimensions:
|
|
125
|
+
|
|
119
126
|
```
|
|
120
|
-
|
|
127
|
+
bl = my.block.reshape(number_of_rows=2, number_of_columns=10)
|
|
121
128
|
```
|
|
122
129
|
|
|
123
130
|
The property `block.highest_used_row_number` returns the row number of the highest non-None cell.
|
|
@@ -152,7 +159,7 @@ Of course, we could access the various input fields with absolute ranges, but if
|
|
|
152
159
|
If we read the project sheet (partly) into a block, lookup methods are available to access *fields* easily and future-proof:
|
|
153
160
|
|
|
154
161
|
```
|
|
155
|
-
bl = xwu.block.
|
|
162
|
+
bl = xwu.block.from_range(sheet.range(1,1),(100,10)))
|
|
156
163
|
```
|
|
157
164
|
|
|
158
165
|
Let's see how this works with the above sheet. The corresponding block (bl) looks like
|
|
@@ -171,7 +178,8 @@ Let's see how this works with the above sheet. The corresponding block (bl) look
|
|
|
171
178
|
9 |
|
|
172
179
|
```
|
|
173
180
|
Now we can do
|
|
174
|
-
```
|
|
181
|
+
```
|
|
182
|
+
project = bl.lookup("Project")
|
|
175
183
|
project = bl.lookup("Project")
|
|
176
184
|
start_date = bl.lookup("Start date")
|
|
177
185
|
end_date = bl.lookup("End date")
|
|
@@ -194,11 +202,11 @@ We then read the following rows (using hlookups) and access the required values.
|
|
|
194
202
|
|
|
195
203
|
### Filling a block from other sources
|
|
196
204
|
|
|
197
|
-
The advantage of using a block instead of accessing these sources is that they are one-based, just like in Excel.
|
|
205
|
+
The advantage of using a block instead of accessing these sources directly is that they are one-based, just like in Excel.
|
|
198
206
|
|
|
199
207
|
It is possible to make a block from an xlrd worksheet with `block.from_xlrd_sheet`.
|
|
200
208
|
|
|
201
|
-
It is possible to create a block from a
|
|
209
|
+
It is possible to create a block from a panda dataFrame using `block.from_dataframe`. Ensure that, if the dataframe is created by reading from an Excel sheet, headers=None is specified, e.g., `df = pd.read_excel(filename, header=None)`.
|
|
202
210
|
|
|
203
211
|
It is possible to make a block from an openpyxl worksheet with `block.from_openpyxl_sheet`.
|
|
204
212
|
|
|
@@ -293,7 +301,7 @@ Just add the .bas file to a worksheet and call like
|
|
|
293
301
|
Sub MacroToExecute()
|
|
294
302
|
DecodeFile(Me, 10, 1)
|
|
295
303
|
```
|
|
296
|
-
|
|
304
|
+
|
|
297
305
|
In this example, the file *film1.mp4* will be downloaded into the current directory.
|
|
298
306
|
|
|
299
307
|
The module xlwings_utils also contains code to encode a local file to a sheet:
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
xlwings_utils/__init__.py,sha256=FdaRztevSu5akGL7KBUBRzqwLMRTdvVUuS2Kfp2f1Uc,68
|
|
2
|
+
xlwings_utils/xlwings_utils.py,sha256=e8Lo40ceG0kSzSuytOpIT3cvJ_bhZRxLC2x69EE6k9Y,28725
|
|
3
|
+
xlwings_utils-25.0.7.dist-info/METADATA,sha256=NVLthhuk58Inh4nNVC9Bvue1VEUXuRUYdjJYKlhEqyA,12418
|
|
4
|
+
xlwings_utils-25.0.7.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
5
|
+
xlwings_utils-25.0.7.dist-info/top_level.txt,sha256=kf5SEv0gZiRObPhUoYcc1O_iX_wwTOPeUIYvzyYeAM4,14
|
|
6
|
+
xlwings_utils-25.0.7.dist-info/RECORD,,
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
xlwings_utils/__init__.py,sha256=FdaRztevSu5akGL7KBUBRzqwLMRTdvVUuS2Kfp2f1Uc,68
|
|
2
|
-
xlwings_utils/xlwings_utils.py,sha256=2OxAeSEvIxSrj5aMMIxAsFYthYKk9yaYVvo8phtaf1c,29626
|
|
3
|
-
xlwings_utils-25.0.6.post5.dist-info/METADATA,sha256=8Ub-c1wDWkoZcW5qXie2w2gqItVa3RMPLjpKaZN7pt8,12255
|
|
4
|
-
xlwings_utils-25.0.6.post5.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
5
|
-
xlwings_utils-25.0.6.post5.dist-info/top_level.txt,sha256=kf5SEv0gZiRObPhUoYcc1O_iX_wwTOPeUIYvzyYeAM4,14
|
|
6
|
-
xlwings_utils-25.0.6.post5.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|