我有一个PDF表单,每个月的每一天都有6个不同的时间段,我需要确保用户完成这些时间段时这些时间段不重叠。并非所有时间段都可以完成,但必须是唯一的。我从之前的Use JavaScript to compare time ranges帖子中汲取了灵感,特别是@RobG的贡献。但是,由于我缺乏脚本知识,因此无法为我的特定应用程序编写该代码。除了要核实时间段外,我还必须每天在表格上重复一次,但是我想一次做到这一点,特别是在当天进行输入时。由于这是PDF表单,因此我不确定如何执行该验证。例如,是否应在每个时间段完成时执行?也就是说,有开始时间和结束时间吗?因此,它将作为该时间输入的“验证”脚本吗? 以下是表单外观的示例:
这是我尝试更新表单代码的尝试:
var TimeIn1 = this.getField("Day1Pd1TimeInRes").value;
var TimeOut1 = this.getField("Day1Pd1TimeOutRes").value;
var TimeIn2 = this.getField("Day1Pd2TimeInRes").value;
var TimeOut2 = this.getField("Day1Pd2TimeOutRes").value;
var TimeIn3 = this.getField("Day1Pd3TimeInRes").value;
var TimeOut3 = this.getField("Day1Pd3TimeOutRes").value;
var TimeIn4 = this.getField("Day1Pd4TimeInRes").value;
var TimeOut4 = this.getField("Day1Pd4TimeOutRes").value;
var TimeIn5 = this.getField("Day1Pd5TimeInRes").value;
var TimeOut5 = this.getField("Day1Pd5TimeOutRes").value;
var TimeIn6 = this.getField("Day1Pd6TimeInRes").value;
var TimeOut6 = this.getField("Day1Pd6TimeOutRes").value;
var timeSlots = [
{BeginTime: new Date("10/25/2015 " + TimeIn1),
EndTime: new Date("10/25/2015 " + TimeOut1)},
{BeginTime: new Date("10/25/2015 " + TimeIn2),
EndTime: new Date("10/25/2015 " + TimeOut2)},
{BeginTime: new Date("10/25/2015 " + TimeIn3),
EndTime: new Date("10/25/2015 " + TimeOut3)},
{BeginTime: new Date("10/25/2015 " + TimeIn4),
EndTime: new Date("10/25/2015 " + TimeOut4)},
{BeginTime: new Date("10/25/2015 " + TimeIn5),
EndTime: new Date("10/25/2015 " + TimeOut5)},
{BeginTime: new Date("10/25/2015 " + TimeIn6),
EndTime: new Date("10/25/2015 " + TimeOut6)}
];
function slotFits(slot) {
if (timeSlots.length == 0) return true; // If no slots, must fit
return timeSlots.some(function(s, i) {
return (i == 0 && slot.EndTime <= s.BeginTime) || //slot is before all others
(s.EndTime <= slot.BeginTime && !timeSlots[i + 1]) || //slot is after all others
(s.EndTime <= slot.BeginTime && timeSlots[i + 1].BeginTime >= slot.EndTime) // Slot between others
});
}
[{BeginTime: new Date("10/25/2015 " + TimeIn1),
EndTime: new Date("10/25/2015 " + TimeOut1)},
{BeginTime: new Date("10/25/2015 " + TimeIn2),
EndTime: new Date("10/25/2015 " + TimeOut2)},
{BeginTime: new Date("10/25/2015 " + TimeIn3),
EndTime: new Date("10/25/2015 " + TimeOut3)},
{BeginTime: new Date("10/25/2015 " + TimeIn4),
EndTime: new Date("10/25/2015 " + TimeOut4)},
{BeginTime: new Date("10/25/2015 " + TimeIn5),
EndTime: new Date("10/25/2015 " + TimeOut5)},
{BeginTime: new Date("10/25/2015 " + TimeIn6),
EndTime: new Date("10/25/2015 " + TimeOut6)},
].forEach(function(slot, i) {
app.alert('Slot ' + i + ': ' + slotFits(slot));
});
在此示例中,我拼写了字段名称,但是由于我一次最多重复31天,因此我想找到一种方法来创建文档脚本,并在其中放入“ TimeIn”和'TimeOut变量并每天调用一次,但是我认为我可以在没有必要的情况下摆脱困境,只需要担心表单大小在6个周期内重复这么多的代码,可能会持续31天。谢谢!
编辑:时间值为HH:mm
答案 0 :(得分:0)
让我们稍微重写一下,因为“事物变得异常复杂”的典型解决方案通常是“选择更好的数据结构”,在这种情况下,这意味着使用Entry表示形式,并为您完成工作。
鉴于Foxit显然不支持现代JS,使用较旧的ES5看起来像:
subset(cbind(A=dat[,1],stack(dat[-1])),values==1,-2)
A ind
1 ex1 S1
4 ex4 S1
7 ex7 S1
10 ex10 S1
12 ex2 S2
14 ex4 S2
15 ex5 S2
16 ex6 S2
17 ex7 S2
18 ex8 S2
23 ex3 S3
27 ex7 S3
28 ex8 S3
29 ex9 S3
35 ex5 S4
library(tidyverse)
dat%>%
gather(Type,j,-A)%>%
filter(j==1)%>%
select(-j)
A Type
1 ex1 S1
2 ex4 S1
3 ex7 S1
4 ex10 S1
5 ex2 S2
6 ex4 S2
7 ex5 S2
8 ex6 S2
9 ex7 S2
10 ex8 S2
11 ex3 S3
12 ex7 S3
13 ex8 S3
14 ex9 S3
15 ex5 S4
然后我们可以使用类似以下代码的对象:
function Entry(pdfObject, day, pd, dateOffset) {
this.id = day + '-' + pd;
this.in = pdfObject.getField('Day'+day+'Pd'+pd+'TimeInRes').value;
this.out = pdfObject.getField('Day'+day+'Pd'+pd+'TimeOutRes').value;
this.begin = new Date(dateOffset+' '+this.in);
this.end = new Date(dateOffset+' '+this.out);
this.interval = this.end.getTime() - this.begin.getTime();
}
Entry.prototype = {
checkFit: function checkFit(entries) {
// 1: find out where our start fits into the list of start times
var start = -1, l = entries.length, other, i, e;
for (i=0; i<l; i++) {
e = entries[i];
if (this.begin < e.begin) {
start = i;
other = e;
}
if (this.begin > e.begin) break;
}
// are we the last entry? if so, we fit if we start after the last end.
if (!other || start === l-1) return (this.begin > entries[l-1].end);
// IF not, there is a next entry; do we end before that begins?
return other.begin <= this.end;
}
}
Entry.loadAll = function loadAll(pdfObject, day, dateOffset) {
return [1,2,3,4,5,6]
.map(function(i) { return new Entry(pdfObject, day, i, dateOffset); })
.sort(function(a,b) { return a.end - b.end; });
}