0
Отвечен

Как посчитать количество нормативных часов между двумя датами?

Игорь Шалдин 6 месяцев назад в Прочее обновлен Гашков Николай (Эксперт) 6 месяцев назад 9

Здравствуйте.

Необходимо вытащить в табличку количество нормативных часов м-ду заданными датами по заданному нормативному календарю.

В  этой  теме нашел скрипт, который вроде как  такое должен сделать:

UsrGetNormPeriod(what,&D1,&D2,numcalend)
{
   int am1 = KDateFromStr(D1).GetAbs();
   int am2 = KDateFromStr(D2).GetAbs();
   int tmrasch = mrasch;
   int tmp = nkalend;
   if ( nkalend!=numcalend && numcalend>0 )
      rwnorma(numcalend,0);
   double Total = 0.;
   for (int am=am1; am<=am2; ++am )
   {
      mrasch=am;
      s118();
      Total += norm(what);
   }
   mrasch=tmrasch;
   if ( nkalend!=tmp )
   {
      rwnorma(tmp,0);
      s118();
   }  
   return Total;
}

Пример вызова:

return UsrGetNormPeriod(2,"01.01.2018","31.12.2018",2);

Но, почему-то, норма часов считается за полные месяцы, а не за заданный период.

Например, если D1 = 01.10.2019   D2 = 10.10.2019, то норма часов считается за полный октябрь. Если D1 = 01.10.2019 D2 = 10.11.2019, то норма часов считается за полные октябрь и ноябрь.

Как исправить? 

Script
На рассмотрении

Добрый день.

Вместо norm() , возвращающую норму за месяц, надо использовать skoljko() для каждого дня (за нужный период)

что типа вот этого:

CountTabelNormCalendDayPeriod(d1,d2,_SimvTabel, _SimvNorm, bHoliday,bFactHours, &Hours)
{
var dateBeg=KDateFromD(GetDateFromFuncRWScript(d1));
var dateEnd=KDateFromD(GetDateFromFuncRWScript(d2));
int TmpMrasch = mrasch;

int CountDay = 0;
double CountHours = 0.;

char SimvTabel[512], SimvNorm[512];
zamena_oboz(_SimvTabel,SimvTabel);
zamena_oboz(_SimvNorm, SimvNorm);

for ( int m=dateBeg.GetAbs(); m<=dateEnd.GetAbs(); m++ )
{
string Holidays = ListHolidays(m);
var razb = CreateObject("ParamFuncRW");
razb.IInitial(Holidays,",",32);
short HolidayDay[32];
for ( int i=0; i < razb.Count(); ++i )
HolidayDay[i]=atoi(razb.Get(i));

s50(m);
int firstDay=m==dateBeg.GetAbs()?dateBeg.GetDay():1;
int lastDay =m==dateEnd.GetAbs()?dateEnd.GetDay():countday;
for ( int day=firstDay; day <= lastDay; day++ )
{
int pos = poisk1(day,HolidayDay,razb.Count(),0);
if ( (bHoliday && pos!=EOF || !bHoliday && pos==EOF) &&
CountChar(SimvTabel,calm[day-1]) && CountChar(SimvNorm,calmras[day-1])
)
{
CountDay++;
double rv;
if(bFactHours)
skoljko(rv,data,day,day,SimvTabel,calm,1);
else
skoljko(rv,data,day,day,SimvNorm,calmras,0);
CountHours += rv;
}
}
}

Hours = CountHours;
if(mrasch!=TmpMrasch)
s50(TmpMrasch);
return CountDay;
}

Использовать так:

double Hours=0;
rwnorma(numcalend,0);
CountTabelNormCalendDayPeriod("20.01.2019","18.02.2019","Р","2", 0,0, Hours);
return Hours;

Я сначала пробовал вставить в функцию приёма такое:

int nch; skoljko(nch,data,d1,d2,"r",calm,0); return nch;

где  d1 и d2  номера дней месяца, м-ду которыми надо посчитать нормативные часы. Но как-то не взлетело. 

Вернее взлетело, но вот так (пробовал получить норму за 1 день):

Что я сделал не так?

Как можно использовать функцию skoljko() вместо norm() в UsrGetNormPeriod ?

1) кажется что d1,d2 - это double вида ГГГГММ.ДД, а функция skoljko ждет в качестве параметров целое число от 1 до 31. (день месяца). 

Должно быть что-то вроде:

s50(am);

int z1,z2;
s6400(d1,d2,z1,z2,data);
double nch; skoljko(nch,data,z1,z2,"r",calmras,0); // calmras - т.к. мы же хотим нормативные часы а не фактические?

2) mrasch = am; - это плохая практика. Лучше s50(am) или s50all(am); В частности тогда не будет рассогласования между mrasch и data. А то тут получаем mrasch соответствует одному месяцу, data - другому.

Вячеслав, я правильно понимаю, что это относится к моей попытке использовать функцию skoljko, а в скрипте, предложенном Николаем, ни чего править не надо? 

Думаю да.

Легко же проверить.. скрипт правильные результаты выдает?

На первый взгляд - да.

А можно узнать зачем вот этот if:

if(bFactHours)
skoljko(rv,data,day,day,SimvTabel,calm,1);
else
skoljko(rv,data,day,day,SimvNorm,calmras,0);

если bFactHours==0, то получим нормативные часы( из графика), иначе часы из табеля

и еще это имеет значение только в том случае если включено ведение часового табеля. В противном случае обе ветки этого if дадут одинаковый результат (нормативные часы).

Сервис поддержки клиентов работает на платформе UserEcho