Spreadsheet-Read
view release on metacpan or search on metacpan
examples/ss-dups-tk.pl view on Meta::CPAN
my ($ft, $r) = @$_;
Spreadsheet::Read::parses ($ft) or next;
push @{$ftyp{$r->[0]}}, @{$r->[1]};
push @{$ftyp{"All spreadsheet types"}}, @{$r->[1]};
}
$tf->Button (
-text => "Select file",
-command => sub {
$ss = undef;
$file = $mw->getOpenFile (
-filetypes => [ ( map { [ $_, $ftyp{$_} ] } sort keys %ftyp ),
[ "All files", "*" ],
],
);
ReadFile ();
},
)->pack (qw(-side left -expand 1 -fill both));
$tf->Button (
-text => "Detect",
-command => \&Detect,
)->pack (qw(-side left -expand 1 -fill both));
$tf->Button (
-text => "Show",
-command => \&Show,
)->pack (qw(-side left -expand 1 -fill both));
$tf->Button (
-text => "Exit",
-command => \&exit,
)->pack (qw(-side left -expand 1 -fill both));
my $mf = $mw->Frame ()->pack (qw( -side top -anchor nw -expand 1 -fill both ));
my $sw = $mf->Scrolled ("ROText",
-scrollbars => "osoe",
-height => 40,
-width => 85,
-foreground => "Black",
-background => "White",
-highlightthickness => 0,
-setgrid => 1)->pack (qw(-expand 1 -fill both));
$dt = $sw->Subwidget ("scrolled");
#$sw->Subwidget ("xscrollbar")->packForget;
$dt->configure (
-wrap => "none",
-font => "mono 12",
);
my $bf = $mw->Frame ()->pack (qw( -side top -anchor nw -expand 1 -fill both ));
$bf->Checkbutton (
-variable => \$opt_t,
-text => "True values only",
)->pack (qw(-side left -expand 1 -fill both));
{ my $opt_S = @opt_S ? join ",", @opt_S : 1;
$bf->Label (
-text => "Sheet(s)",
)->pack (qw(-side left -expand 1 -fill both));
$bf->Entry (
-textvariable => \$opt_S,
-width => 10,
-validate => "focusout",
-vcmd => sub {
@opt_S = grep m/\S/, split m/\s*,\s*/ => $opt_S;
1;
},
)->pack (qw(-side left -expand 1 -fill both));
}
{ my $opt_R = join ",", @opt_R;
$bf->Label (
-text => "Rows(s)",
)->pack (qw(-side left -expand 1 -fill both));
$bf->Entry (
-textvariable => \$opt_R,
-width => 10,
-validate => "focusout",
-vcmd => sub {
@opt_R = grep m/\S/, split m/\s*,\s*/ => $opt_R;
1;
},
)->pack (qw(-side left -expand 1 -fill both));
}
{ my $opt_C = join ",", @opt_C;
$bf->Label (
-text => "Columns(s)",
)->pack (qw(-side left -expand 1 -fill both));
$bf->Entry (
-textvariable => \$opt_C,
-width => 10,
-validate => "focusout",
-vcmd => sub {
@opt_C = grep m/\S/, split m/\s*,\s*/ => $opt_C;
1;
},
)->pack (qw(-side left -expand 1 -fill both));
}
sub ranges (@) {
my @g;
foreach my $arg (@_) {
for (split m/,/, $arg) {
if (m/^(\w+)\.\.(\w+)$/) {
my ($s, $e) = ($1, $2);
$s =~ m/^[1-9]\d*$/ or ($s, $e) = (qq("$s"), qq("$e"));
eval "push \@g, $s .. $e";
}
else {
push @g, $_;
}
}
}
$opt_v and print STDERR "( @g )\n";
@g;
} # ranges
sub Detect {
$ss or ReadFile ();
$dt->delete ($is, "end");
$dt->insert ("end", join "\n", "",
"Shts: @opt_S",
"Rows: @opt_R",
"Cols: @opt_C",
"--------------------------------------------------------------",
"");
my %done;
my @S = $opt_S[0] eq "all" ? (1 .. $ss->[0]{sheets}) : ranges (@opt_S);
my @R = ranges (@opt_R);
my @C = ranges (@opt_C);
my %f = map { uc $_ => 1 } ("@opt_F" =~ m/(\b[A-Z]\d+\b)/ig);
foreach my $s (@S) {
my $xls = $ss->[$s] or die "Cannot read sheet $s\n";
my @r = @R ? @R : (1 .. $xls->{maxrow});
my @c = @C ? @C : (1 .. $xls->{maxcol});
foreach my $r (@r) {
foreach my $c (@c) {
defined $xls->{cell}[$c][$r] or next;
my $v = uc $xls->{cell}[$c][$r];
my $cell = cr2cell ($c, $r);
@S > 1 and $cell = $xls->{label} . "[$cell]";
$opt_t && !$v and next;
@opt_F && !exists $f{$cell} and next;
if (exists $done{$v}) {
$dt->insert ("end", sprintf "Cell %-5s is dup of %-5s '%s'\n", $cell, $done{$v}, $v);
next;
}
$done{$v} = $cell;
}
}
}
} # Detect
sub Show {
$ss or ReadFile ();
$dt->delete ($is, "end");
( run in 1.461 second using v1.01-cache-2.11-cpan-5511b514fd6 )