- Deprecated function: Use of "static" in callables is deprecated in Drupal\user\Entity\Role::postLoad() (line 172 of core/modules/user/src/Entity/Role.php).
Drupal\user\Entity\Role::postLoad(Object, Array) (Line: 423)
Drupal\Core\Entity\EntityStorageBase->postLoad(Array) (Line: 353)
Drupal\Core\Entity\EntityStorageBase->loadMultiple(Array) (Line: 16)
Drupal\user\RoleStorage->isPermissionInRoles('access site in maintenance mode', Array) (Line: 112)
Drupal\Core\Session\UserSession->hasPermission('access site in maintenance mode') (Line: 105)
Drupal\Core\Session\AccountProxy->hasPermission('access site in maintenance mode') (Line: 83)
Drupal\redirect\RedirectChecker->canRedirect(Object) (Line: 120)
Drupal\redirect\EventSubscriber\RedirectRequestSubscriber->onKernelRequestCheckRedirect(Object, 'kernel.request', Object)
call_user_func(Array, Object, 'kernel.request', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.request') (Line: 145)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
- Deprecated function: Creation of dynamic property Drupal\views\ManyToOneHelper::$handler is deprecated in Drupal\views\ManyToOneHelper->__construct() (line 24 of core/modules/views/src/ManyToOneHelper.php).
Drupal\views\ManyToOneHelper->__construct(Object) (Line: 54)
Drupal\views\Plugin\views\argument\ManyToOne->defineOptions() (Line: 141)
Drupal\views\Plugin\views\PluginBase->init(Object, Object, Array) (Line: 104)
Drupal\views\Plugin\views\HandlerBase->init(Object, Object, Array) (Line: 82)
Drupal\views\Plugin\views\argument\ArgumentPluginBase->init(Object, Object, Array) (Line: 33)
Drupal\views\Plugin\views\argument\ManyToOne->init(Object, Object, Array) (Line: 894)
Drupal\views\Plugin\views\display\DisplayPluginBase->getHandlers('argument') (Line: 1045)
Drupal\views\ViewExecutable->_initHandler('argument', Array) (Line: 903)
Drupal\views\ViewExecutable->initHandlers() (Line: 2318)
Drupal\views\Plugin\views\display\DisplayPluginBase->preExecute() (Line: 1697)
Drupal\views\ViewExecutable->preExecute(Array) (Line: 1632)
Drupal\views\ViewExecutable->executeDisplay('page_1', Array) (Line: 81)
Drupal\views\Element\View::preRenderViewElement(Array)
call_user_func_array(Array, Array) (Line: 101)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, ) (Line: 242)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
- Deprecated function: Creation of dynamic property Drupal\views\ManyToOneHelper::$handler is deprecated in Drupal\views\ManyToOneHelper->__construct() (line 24 of core/modules/views/src/ManyToOneHelper.php).
Drupal\views\ManyToOneHelper->__construct(Object) (Line: 54)
Drupal\views\Plugin\views\argument\ManyToOne->defineOptions() (Line: 228)
Drupal\views\Plugin\views\PluginBase->unpackOptions(Array, Array) (Line: 144)
Drupal\views\Plugin\views\PluginBase->init(Object, Object, Array) (Line: 104)
Drupal\views\Plugin\views\HandlerBase->init(Object, Object, Array) (Line: 82)
Drupal\views\Plugin\views\argument\ArgumentPluginBase->init(Object, Object, Array) (Line: 33)
Drupal\views\Plugin\views\argument\ManyToOne->init(Object, Object, Array) (Line: 894)
Drupal\views\Plugin\views\display\DisplayPluginBase->getHandlers('argument') (Line: 1045)
Drupal\views\ViewExecutable->_initHandler('argument', Array) (Line: 903)
Drupal\views\ViewExecutable->initHandlers() (Line: 2318)
Drupal\views\Plugin\views\display\DisplayPluginBase->preExecute() (Line: 1697)
Drupal\views\ViewExecutable->preExecute(Array) (Line: 1632)
Drupal\views\ViewExecutable->executeDisplay('page_1', Array) (Line: 81)
Drupal\views\Element\View::preRenderViewElement(Array)
call_user_func_array(Array, Array) (Line: 101)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, ) (Line: 242)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
- Deprecated function: Creation of dynamic property Drupal\views\ManyToOneHelper::$handler is deprecated in Drupal\views\ManyToOneHelper->__construct() (line 24 of core/modules/views/src/ManyToOneHelper.php).
Drupal\views\ManyToOneHelper->__construct(Object) (Line: 54)
Drupal\views\Plugin\views\argument\ManyToOne->defineOptions() (Line: 228)
Drupal\views\Plugin\views\PluginBase->unpackOptions(Array, Array) (Line: 110)
Drupal\views\Plugin\views\HandlerBase->init(Object, Object, Array) (Line: 82)
Drupal\views\Plugin\views\argument\ArgumentPluginBase->init(Object, Object, Array) (Line: 33)
Drupal\views\Plugin\views\argument\ManyToOne->init(Object, Object, Array) (Line: 894)
Drupal\views\Plugin\views\display\DisplayPluginBase->getHandlers('argument') (Line: 1045)
Drupal\views\ViewExecutable->_initHandler('argument', Array) (Line: 903)
Drupal\views\ViewExecutable->initHandlers() (Line: 2318)
Drupal\views\Plugin\views\display\DisplayPluginBase->preExecute() (Line: 1697)
Drupal\views\ViewExecutable->preExecute(Array) (Line: 1632)
Drupal\views\ViewExecutable->executeDisplay('page_1', Array) (Line: 81)
Drupal\views\Element\View::preRenderViewElement(Array)
call_user_func_array(Array, Array) (Line: 101)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, ) (Line: 242)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
- Deprecated function: Creation of dynamic property Drupal\views\ManyToOneHelper::$handler is deprecated in Drupal\views\ManyToOneHelper->__construct() (line 24 of core/modules/views/src/ManyToOneHelper.php).
Drupal\views\ManyToOneHelper->__construct(Object) (Line: 35)
Drupal\views\Plugin\views\argument\ManyToOne->init(Object, Object, Array) (Line: 894)
Drupal\views\Plugin\views\display\DisplayPluginBase->getHandlers('argument') (Line: 1045)
Drupal\views\ViewExecutable->_initHandler('argument', Array) (Line: 903)
Drupal\views\ViewExecutable->initHandlers() (Line: 2318)
Drupal\views\Plugin\views\display\DisplayPluginBase->preExecute() (Line: 1697)
Drupal\views\ViewExecutable->preExecute(Array) (Line: 1632)
Drupal\views\ViewExecutable->executeDisplay('page_1', Array) (Line: 81)
Drupal\views\Element\View::preRenderViewElement(Array)
call_user_func_array(Array, Array) (Line: 101)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, ) (Line: 242)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
- Deprecated function: Creation of dynamic property Drupal\mysql\Driver\Database\mysql\Select::$alterTags is deprecated in Drupal\Core\Database\Query\Select->addTag() (line 149 of core/lib/Drupal/Core/Database/Query/Select.php).
Drupal\Core\Database\Query\Select->addTag('views') (Line: 1316)
Drupal\views\Plugin\views\query\Sql->query() (Line: 1454)
Drupal\views\Plugin\views\query\Sql->build(Object) (Line: 1326)
Drupal\views\ViewExecutable->build() (Line: 392)
Drupal\views\Plugin\views\display\PathPluginBase->execute() (Line: 196)
Drupal\views\Plugin\views\display\Page->execute() (Line: 1635)
Drupal\views\ViewExecutable->executeDisplay('page_1', Array) (Line: 81)
Drupal\views\Element\View::preRenderViewElement(Array)
call_user_func_array(Array, Array) (Line: 101)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, ) (Line: 242)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
- Deprecated function: Creation of dynamic property Drupal\mysql\Driver\Database\mysql\Select::$alterMetaData is deprecated in Drupal\Core\Database\Query\Select->addMetaData() (line 178 of core/lib/Drupal/Core/Database/Query/Select.php).
Drupal\Core\Database\Query\Select->addMetaData('views_substitutions', Array) (Line: 1418)
Drupal\views\Plugin\views\query\Sql->query() (Line: 1454)
Drupal\views\Plugin\views\query\Sql->build(Object) (Line: 1326)
Drupal\views\ViewExecutable->build() (Line: 392)
Drupal\views\Plugin\views\display\PathPluginBase->execute() (Line: 196)
Drupal\views\Plugin\views\display\Page->execute() (Line: 1635)
Drupal\views\ViewExecutable->executeDisplay('page_1', Array) (Line: 81)
Drupal\views\Element\View::preRenderViewElement(Array)
call_user_func_array(Array, Array) (Line: 101)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, ) (Line: 242)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
- Deprecated function: Creation of dynamic property Drupal\mysql\Driver\Database\mysql\Select::$alterTags is deprecated in Drupal\Core\Database\Query\Select->addTag() (line 149 of core/lib/Drupal/Core/Database/Query/Select.php).
Drupal\Core\Database\Query\Select->addTag('views') (Line: 1316)
Drupal\views\Plugin\views\query\Sql->query(1) (Line: 1455)
Drupal\views\Plugin\views\query\Sql->build(Object) (Line: 1326)
Drupal\views\ViewExecutable->build() (Line: 392)
Drupal\views\Plugin\views\display\PathPluginBase->execute() (Line: 196)
Drupal\views\Plugin\views\display\Page->execute() (Line: 1635)
Drupal\views\ViewExecutable->executeDisplay('page_1', Array) (Line: 81)
Drupal\views\Element\View::preRenderViewElement(Array)
call_user_func_array(Array, Array) (Line: 101)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, ) (Line: 242)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
- Deprecated function: Creation of dynamic property Drupal\mysql\Driver\Database\mysql\Select::$alterMetaData is deprecated in Drupal\Core\Database\Query\Select->addMetaData() (line 178 of core/lib/Drupal/Core/Database/Query/Select.php).
Drupal\Core\Database\Query\Select->addMetaData('views_substitutions', Array) (Line: 1418)
Drupal\views\Plugin\views\query\Sql->query(1) (Line: 1455)
Drupal\views\Plugin\views\query\Sql->build(Object) (Line: 1326)
Drupal\views\ViewExecutable->build() (Line: 392)
Drupal\views\Plugin\views\display\PathPluginBase->execute() (Line: 196)
Drupal\views\Plugin\views\display\Page->execute() (Line: 1635)
Drupal\views\ViewExecutable->executeDisplay('page_1', Array) (Line: 81)
Drupal\views\Element\View::preRenderViewElement(Array)
call_user_func_array(Array, Array) (Line: 101)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, ) (Line: 242)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
- Deprecated function: Creation of dynamic property Drupal\views\ManyToOneHelper::$handler is deprecated in Drupal\views\ManyToOneHelper->__construct() (line 24 of core/modules/views/src/ManyToOneHelper.php).
Drupal\views\ManyToOneHelper->__construct(Object) (Line: 54)
Drupal\views\Plugin\views\argument\ManyToOne->defineOptions() (Line: 141)
Drupal\views\Plugin\views\PluginBase->init(Object, Object, Array) (Line: 104)
Drupal\views\Plugin\views\HandlerBase->init(Object, Object, Array) (Line: 82)
Drupal\views\Plugin\views\argument\ArgumentPluginBase->init(Object, Object, Array) (Line: 33)
Drupal\views\Plugin\views\argument\ManyToOne->init(Object, Object, Array) (Line: 894)
Drupal\views\Plugin\views\display\DisplayPluginBase->getHandlers('argument') (Line: 1045)
Drupal\views\ViewExecutable->_initHandler('argument', Array) (Line: 903)
Drupal\views\ViewExecutable->initHandlers() (Line: 1876)
Drupal\views\ViewExecutable->buildTitle() (Line: 338)
Drupal\views\Plugin\views\display\Feed->attachTo(Object, 'page_1', Array) (Line: 1733)
Drupal\views\ViewExecutable->attachDisplays() (Line: 1333)
Drupal\views\ViewExecutable->build() (Line: 392)
Drupal\views\Plugin\views\display\PathPluginBase->execute() (Line: 196)
Drupal\views\Plugin\views\display\Page->execute() (Line: 1635)
Drupal\views\ViewExecutable->executeDisplay('page_1', Array) (Line: 81)
Drupal\views\Element\View::preRenderViewElement(Array)
call_user_func_array(Array, Array) (Line: 101)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, ) (Line: 242)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
- Deprecated function: Creation of dynamic property Drupal\views\ManyToOneHelper::$handler is deprecated in Drupal\views\ManyToOneHelper->__construct() (line 24 of core/modules/views/src/ManyToOneHelper.php).
Drupal\views\ManyToOneHelper->__construct(Object) (Line: 54)
Drupal\views\Plugin\views\argument\ManyToOne->defineOptions() (Line: 228)
Drupal\views\Plugin\views\PluginBase->unpackOptions(Array, Array) (Line: 144)
Drupal\views\Plugin\views\PluginBase->init(Object, Object, Array) (Line: 104)
Drupal\views\Plugin\views\HandlerBase->init(Object, Object, Array) (Line: 82)
Drupal\views\Plugin\views\argument\ArgumentPluginBase->init(Object, Object, Array) (Line: 33)
Drupal\views\Plugin\views\argument\ManyToOne->init(Object, Object, Array) (Line: 894)
Drupal\views\Plugin\views\display\DisplayPluginBase->getHandlers('argument') (Line: 1045)
Drupal\views\ViewExecutable->_initHandler('argument', Array) (Line: 903)
Drupal\views\ViewExecutable->initHandlers() (Line: 1876)
Drupal\views\ViewExecutable->buildTitle() (Line: 338)
Drupal\views\Plugin\views\display\Feed->attachTo(Object, 'page_1', Array) (Line: 1733)
Drupal\views\ViewExecutable->attachDisplays() (Line: 1333)
Drupal\views\ViewExecutable->build() (Line: 392)
Drupal\views\Plugin\views\display\PathPluginBase->execute() (Line: 196)
Drupal\views\Plugin\views\display\Page->execute() (Line: 1635)
Drupal\views\ViewExecutable->executeDisplay('page_1', Array) (Line: 81)
Drupal\views\Element\View::preRenderViewElement(Array)
call_user_func_array(Array, Array) (Line: 101)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, ) (Line: 242)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
- Deprecated function: Creation of dynamic property Drupal\views\ManyToOneHelper::$handler is deprecated in Drupal\views\ManyToOneHelper->__construct() (line 24 of core/modules/views/src/ManyToOneHelper.php).
Drupal\views\ManyToOneHelper->__construct(Object) (Line: 54)
Drupal\views\Plugin\views\argument\ManyToOne->defineOptions() (Line: 228)
Drupal\views\Plugin\views\PluginBase->unpackOptions(Array, Array) (Line: 110)
Drupal\views\Plugin\views\HandlerBase->init(Object, Object, Array) (Line: 82)
Drupal\views\Plugin\views\argument\ArgumentPluginBase->init(Object, Object, Array) (Line: 33)
Drupal\views\Plugin\views\argument\ManyToOne->init(Object, Object, Array) (Line: 894)
Drupal\views\Plugin\views\display\DisplayPluginBase->getHandlers('argument') (Line: 1045)
Drupal\views\ViewExecutable->_initHandler('argument', Array) (Line: 903)
Drupal\views\ViewExecutable->initHandlers() (Line: 1876)
Drupal\views\ViewExecutable->buildTitle() (Line: 338)
Drupal\views\Plugin\views\display\Feed->attachTo(Object, 'page_1', Array) (Line: 1733)
Drupal\views\ViewExecutable->attachDisplays() (Line: 1333)
Drupal\views\ViewExecutable->build() (Line: 392)
Drupal\views\Plugin\views\display\PathPluginBase->execute() (Line: 196)
Drupal\views\Plugin\views\display\Page->execute() (Line: 1635)
Drupal\views\ViewExecutable->executeDisplay('page_1', Array) (Line: 81)
Drupal\views\Element\View::preRenderViewElement(Array)
call_user_func_array(Array, Array) (Line: 101)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, ) (Line: 242)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
- Deprecated function: Creation of dynamic property Drupal\views\ManyToOneHelper::$handler is deprecated in Drupal\views\ManyToOneHelper->__construct() (line 24 of core/modules/views/src/ManyToOneHelper.php).
Drupal\views\ManyToOneHelper->__construct(Object) (Line: 35)
Drupal\views\Plugin\views\argument\ManyToOne->init(Object, Object, Array) (Line: 894)
Drupal\views\Plugin\views\display\DisplayPluginBase->getHandlers('argument') (Line: 1045)
Drupal\views\ViewExecutable->_initHandler('argument', Array) (Line: 903)
Drupal\views\ViewExecutable->initHandlers() (Line: 1876)
Drupal\views\ViewExecutable->buildTitle() (Line: 338)
Drupal\views\Plugin\views\display\Feed->attachTo(Object, 'page_1', Array) (Line: 1733)
Drupal\views\ViewExecutable->attachDisplays() (Line: 1333)
Drupal\views\ViewExecutable->build() (Line: 392)
Drupal\views\Plugin\views\display\PathPluginBase->execute() (Line: 196)
Drupal\views\Plugin\views\display\Page->execute() (Line: 1635)
Drupal\views\ViewExecutable->executeDisplay('page_1', Array) (Line: 81)
Drupal\views\Element\View::preRenderViewElement(Array)
call_user_func_array(Array, Array) (Line: 101)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, ) (Line: 242)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
- Deprecated function: Creation of dynamic property Drupal\mysql\Driver\Database\mysql\Select::$alterTags is deprecated in Drupal\Core\Database\Query\Select->addTag() (line 149 of core/lib/Drupal/Core/Database/Query/Select.php).
Drupal\Core\Database\Query\Select->addTag('node_load_multiple') (Line: 696)
Drupal\Core\Entity\Sql\SqlContentEntityStorage->buildQuery(Array) (Line: 422)
Drupal\Core\Entity\Sql\SqlContentEntityStorage->getFromStorage(Array) (Line: 393)
Drupal\Core\Entity\Sql\SqlContentEntityStorage->doLoadMultiple(Array) (Line: 346)
Drupal\Core\Entity\EntityStorageBase->loadMultiple(Array) (Line: 1616)
Drupal\views\Plugin\views\query\Sql->loadEntities(Array) (Line: 1541)
Drupal\views\Plugin\views\query\Sql->execute(Object) (Line: 1431)
Drupal\views\ViewExecutable->execute(NULL) (Line: 1459)
Drupal\views\ViewExecutable->render() (Line: 199)
Drupal\views\Plugin\views\display\Page->execute() (Line: 1635)
Drupal\views\ViewExecutable->executeDisplay('page_1', Array) (Line: 81)
Drupal\views\Element\View::preRenderViewElement(Array)
call_user_func_array(Array, Array) (Line: 101)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, ) (Line: 242)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
- Deprecated function: Creation of dynamic property Drupal\mysql\Driver\Database\mysql\Select::$alterMetaData is deprecated in Drupal\Core\Database\Query\Select->addMetaData() (line 178 of core/lib/Drupal/Core/Database/Query/Select.php).
Drupal\Core\Database\Query\Select->addMetaData('entity_type', 'file') (Line: 115)
Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80)
Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640)
Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63)
Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', 'd6d9cff4-3b60-4c41-8756-9296b87fb31e') (Line: 95)
Drupal\editor\Plugin\Filter\EditorFileReference->process('La función <a href="/es/dax/function/totalytd">TOTALYTD</a> es fácil de usar y nos permite calcular rápidamente el resultado de una expresión para el período transcurrido entre el 1 de enero y la última fecha del contexto actual, pero en ocasiones nos encontraremos con que necesitamos un mayor control sobre la expresión evaluada. En este escenario vamos a simular la función TOTALYTD utilizando otras funciones que nos permitirían ese control adicional.
Partimos de una tabla denominada Movements donde encontramos movimientos financieros asociados a una fecha (supongamos que se trata de ventas):
Por otro lado, por supuesto, tenemos una tabla conteniendo un calendario (tabla Calendar):
Ambas tablas están relacionadas por el campo de fecha. Para simular la función TOTALYTD queremos calcular el acumulado del campo Movements[Total]<em> </em>desde principio de año (del período involucrado en el contexto actual) hasta la última fecha del "período actual".
La expresión base será la suma del campo Movements[Total], expresión que servirá de primer argumento de la función <a href="/es/dax/function/calculate">CALCULATE</a>, a la que deberemos añadir como segundo argumento la modificación del contexto de filtro a aplicar. En pseudo-código, la medida a crear es la siguiente:
Running Total =
CALCULATE(
SUM(Movements[Total]),
Período entre el 1 de enero del año actual hasta el último día del período actual
)
Para el cálculo del período en cuestión (entre el 1 de enero del año correspondiente y el último día del contexto actual) podemos recurrir a filtrar la tabla Calendar con la función <a href="/es/dax/function/filter">FILTER</a> de forma que, dado un contexto actual, seleccione aquellos registros del calendario que involucren las fechas de interés. Es decir, nuestro pseudo-código quedaría así:
Running Total =
CALCULATE(
SUM(Movements[Total]),
FILTER(
Calendar,
Período entre el 1 de enero del año actual hasta el último día del período actual
)
)
Con la función <a href="/es/dax/function/max">MAX</a> aplicada al calendario podemos calcular tanto el último día del contexto actual (aplicando la función al campo Date) como el año siendo considerado (aplicando la función al campo Año), por lo que para extraer el período de interés podríamos imponer dos condiciones:
<ol><li>Que la fecha del calendario sea inferior al último día del contexto actual</li>
<li>Que el año del calendario sea igual al año del contexto actual</li>
</ol>Es decir:
Running Total =
CALCULATE(
SUM(Movements[Total]),
FILTER(
Calendar,
Fecha del calendario anterior al último día del contexto actual Y
Año del calendario igual al año del contexto actual
)
)
Llevando los campos y funciones reales al pseudo-código anterior tenemos:
Running Total =
CALCULATE(
SUM(Movements[Total]),
FILTER(
ALL('Calendar'),
'Calendar'[Date] <= MAX('Calendar'[Date]) &&
'Calendar'[Año] = MAX('Calendar'[Año]
)
)
)
Debemos asegurarnos de que la tabla Calendar no está siendo filtrada, por lo que se aplica la función <a href="/es/dax/function/all">ALL</a> (de otro modo se contextualizaría y no nos permitiría siempre extraer el período transcurrido desde principio de año).
', 'es') (Line: 118)
Drupal\filter\Element\ProcessedText::preRenderText(Array)
call_user_func_array(Array, Array) (Line: 101)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88)
__TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 46)
__TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 43)
__TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110)
__TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, ) (Line: 242)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
- Deprecated function: Creation of dynamic property Drupal\mysql\Driver\Database\mysql\Select::$alterTags is deprecated in Drupal\Core\Database\Query\Select->addTag() (line 149 of core/lib/Drupal/Core/Database/Query/Select.php).
Drupal\Core\Database\Query\Select->addTag('entity_query') (Line: 147)
Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80)
Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640)
Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63)
Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', 'd6d9cff4-3b60-4c41-8756-9296b87fb31e') (Line: 95)
Drupal\editor\Plugin\Filter\EditorFileReference->process('La función <a href="/es/dax/function/totalytd">TOTALYTD</a> es fácil de usar y nos permite calcular rápidamente el resultado de una expresión para el período transcurrido entre el 1 de enero y la última fecha del contexto actual, pero en ocasiones nos encontraremos con que necesitamos un mayor control sobre la expresión evaluada. En este escenario vamos a simular la función TOTALYTD utilizando otras funciones que nos permitirían ese control adicional.
Partimos de una tabla denominada Movements donde encontramos movimientos financieros asociados a una fecha (supongamos que se trata de ventas):
Por otro lado, por supuesto, tenemos una tabla conteniendo un calendario (tabla Calendar):
Ambas tablas están relacionadas por el campo de fecha. Para simular la función TOTALYTD queremos calcular el acumulado del campo Movements[Total]<em> </em>desde principio de año (del período involucrado en el contexto actual) hasta la última fecha del "período actual".
La expresión base será la suma del campo Movements[Total], expresión que servirá de primer argumento de la función <a href="/es/dax/function/calculate">CALCULATE</a>, a la que deberemos añadir como segundo argumento la modificación del contexto de filtro a aplicar. En pseudo-código, la medida a crear es la siguiente:
Running Total =
CALCULATE(
SUM(Movements[Total]),
Período entre el 1 de enero del año actual hasta el último día del período actual
)
Para el cálculo del período en cuestión (entre el 1 de enero del año correspondiente y el último día del contexto actual) podemos recurrir a filtrar la tabla Calendar con la función <a href="/es/dax/function/filter">FILTER</a> de forma que, dado un contexto actual, seleccione aquellos registros del calendario que involucren las fechas de interés. Es decir, nuestro pseudo-código quedaría así:
Running Total =
CALCULATE(
SUM(Movements[Total]),
FILTER(
Calendar,
Período entre el 1 de enero del año actual hasta el último día del período actual
)
)
Con la función <a href="/es/dax/function/max">MAX</a> aplicada al calendario podemos calcular tanto el último día del contexto actual (aplicando la función al campo Date) como el año siendo considerado (aplicando la función al campo Año), por lo que para extraer el período de interés podríamos imponer dos condiciones:
<ol><li>Que la fecha del calendario sea inferior al último día del contexto actual</li>
<li>Que el año del calendario sea igual al año del contexto actual</li>
</ol>Es decir:
Running Total =
CALCULATE(
SUM(Movements[Total]),
FILTER(
Calendar,
Fecha del calendario anterior al último día del contexto actual Y
Año del calendario igual al año del contexto actual
)
)
Llevando los campos y funciones reales al pseudo-código anterior tenemos:
Running Total =
CALCULATE(
SUM(Movements[Total]),
FILTER(
ALL('Calendar'),
'Calendar'[Date] <= MAX('Calendar'[Date]) &&
'Calendar'[Año] = MAX('Calendar'[Año]
)
)
)
Debemos asegurarnos de que la tabla Calendar no está siendo filtrada, por lo que se aplica la función <a href="/es/dax/function/all">ALL</a> (de otro modo se contextualizaría y no nos permitiría siempre extraer el período transcurrido desde principio de año).
', 'es') (Line: 118)
Drupal\filter\Element\ProcessedText::preRenderText(Array)
call_user_func_array(Array, Array) (Line: 101)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88)
__TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 46)
__TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 43)
__TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110)
__TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, ) (Line: 242)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
- Deprecated function: Creation of dynamic property Drupal\mysql\Driver\Database\mysql\Select::$alterTags is deprecated in Drupal\Core\Database\Query\Select->addTag() (line 149 of core/lib/Drupal/Core/Database/Query/Select.php).
Drupal\Core\Database\Query\Select->addTag('file_load_multiple') (Line: 696)
Drupal\Core\Entity\Sql\SqlContentEntityStorage->buildQuery(Array) (Line: 422)
Drupal\Core\Entity\Sql\SqlContentEntityStorage->getFromStorage(Array) (Line: 393)
Drupal\Core\Entity\Sql\SqlContentEntityStorage->doLoadMultiple(Array) (Line: 346)
Drupal\Core\Entity\EntityStorageBase->loadMultiple(Array) (Line: 641)
Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63)
Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', 'd6d9cff4-3b60-4c41-8756-9296b87fb31e') (Line: 95)
Drupal\editor\Plugin\Filter\EditorFileReference->process('La función <a href="/es/dax/function/totalytd">TOTALYTD</a> es fácil de usar y nos permite calcular rápidamente el resultado de una expresión para el período transcurrido entre el 1 de enero y la última fecha del contexto actual, pero en ocasiones nos encontraremos con que necesitamos un mayor control sobre la expresión evaluada. En este escenario vamos a simular la función TOTALYTD utilizando otras funciones que nos permitirían ese control adicional.
Partimos de una tabla denominada Movements donde encontramos movimientos financieros asociados a una fecha (supongamos que se trata de ventas):
Por otro lado, por supuesto, tenemos una tabla conteniendo un calendario (tabla Calendar):
Ambas tablas están relacionadas por el campo de fecha. Para simular la función TOTALYTD queremos calcular el acumulado del campo Movements[Total]<em> </em>desde principio de año (del período involucrado en el contexto actual) hasta la última fecha del "período actual".
La expresión base será la suma del campo Movements[Total], expresión que servirá de primer argumento de la función <a href="/es/dax/function/calculate">CALCULATE</a>, a la que deberemos añadir como segundo argumento la modificación del contexto de filtro a aplicar. En pseudo-código, la medida a crear es la siguiente:
Running Total =
CALCULATE(
SUM(Movements[Total]),
Período entre el 1 de enero del año actual hasta el último día del período actual
)
Para el cálculo del período en cuestión (entre el 1 de enero del año correspondiente y el último día del contexto actual) podemos recurrir a filtrar la tabla Calendar con la función <a href="/es/dax/function/filter">FILTER</a> de forma que, dado un contexto actual, seleccione aquellos registros del calendario que involucren las fechas de interés. Es decir, nuestro pseudo-código quedaría así:
Running Total =
CALCULATE(
SUM(Movements[Total]),
FILTER(
Calendar,
Período entre el 1 de enero del año actual hasta el último día del período actual
)
)
Con la función <a href="/es/dax/function/max">MAX</a> aplicada al calendario podemos calcular tanto el último día del contexto actual (aplicando la función al campo Date) como el año siendo considerado (aplicando la función al campo Año), por lo que para extraer el período de interés podríamos imponer dos condiciones:
<ol><li>Que la fecha del calendario sea inferior al último día del contexto actual</li>
<li>Que el año del calendario sea igual al año del contexto actual</li>
</ol>Es decir:
Running Total =
CALCULATE(
SUM(Movements[Total]),
FILTER(
Calendar,
Fecha del calendario anterior al último día del contexto actual Y
Año del calendario igual al año del contexto actual
)
)
Llevando los campos y funciones reales al pseudo-código anterior tenemos:
Running Total =
CALCULATE(
SUM(Movements[Total]),
FILTER(
ALL('Calendar'),
'Calendar'[Date] <= MAX('Calendar'[Date]) &&
'Calendar'[Año] = MAX('Calendar'[Año]
)
)
)
Debemos asegurarnos de que la tabla Calendar no está siendo filtrada, por lo que se aplica la función <a href="/es/dax/function/all">ALL</a> (de otro modo se contextualizaría y no nos permitiría siempre extraer el período transcurrido desde principio de año).
', 'es') (Line: 118)
Drupal\filter\Element\ProcessedText::preRenderText(Array)
call_user_func_array(Array, Array) (Line: 101)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88)
__TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 46)
__TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 43)
__TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110)
__TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, ) (Line: 242)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
- Deprecated function: Creation of dynamic property Drupal\mysql\Driver\Database\mysql\Select::$alterMetaData is deprecated in Drupal\Core\Database\Query\Select->addMetaData() (line 178 of core/lib/Drupal/Core/Database/Query/Select.php).
Drupal\Core\Database\Query\Select->addMetaData('entity_type', 'file') (Line: 115)
Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80)
Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640)
Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63)
Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', 'd6d9cff4-3b60-4c41-8756-9296b87fb31e') (Line: 124)
Drupal\editor\Plugin\Filter\EditorFileReference->process('La función <a href="/es/dax/function/totalytd">TOTALYTD</a> es fácil de usar y nos permite calcular rápidamente el resultado de una expresión para el período transcurrido entre el 1 de enero y la última fecha del contexto actual, pero en ocasiones nos encontraremos con que necesitamos un mayor control sobre la expresión evaluada. En este escenario vamos a simular la función TOTALYTD utilizando otras funciones que nos permitirían ese control adicional.
Partimos de una tabla denominada Movements donde encontramos movimientos financieros asociados a una fecha (supongamos que se trata de ventas):
Por otro lado, por supuesto, tenemos una tabla conteniendo un calendario (tabla Calendar):
Ambas tablas están relacionadas por el campo de fecha. Para simular la función TOTALYTD queremos calcular el acumulado del campo Movements[Total]<em> </em>desde principio de año (del período involucrado en el contexto actual) hasta la última fecha del "período actual".
La expresión base será la suma del campo Movements[Total], expresión que servirá de primer argumento de la función <a href="/es/dax/function/calculate">CALCULATE</a>, a la que deberemos añadir como segundo argumento la modificación del contexto de filtro a aplicar. En pseudo-código, la medida a crear es la siguiente:
Running Total =
CALCULATE(
SUM(Movements[Total]),
Período entre el 1 de enero del año actual hasta el último día del período actual
)
Para el cálculo del período en cuestión (entre el 1 de enero del año correspondiente y el último día del contexto actual) podemos recurrir a filtrar la tabla Calendar con la función <a href="/es/dax/function/filter">FILTER</a> de forma que, dado un contexto actual, seleccione aquellos registros del calendario que involucren las fechas de interés. Es decir, nuestro pseudo-código quedaría así:
Running Total =
CALCULATE(
SUM(Movements[Total]),
FILTER(
Calendar,
Período entre el 1 de enero del año actual hasta el último día del período actual
)
)
Con la función <a href="/es/dax/function/max">MAX</a> aplicada al calendario podemos calcular tanto el último día del contexto actual (aplicando la función al campo Date) como el año siendo considerado (aplicando la función al campo Año), por lo que para extraer el período de interés podríamos imponer dos condiciones:
<ol><li>Que la fecha del calendario sea inferior al último día del contexto actual</li>
<li>Que el año del calendario sea igual al año del contexto actual</li>
</ol>Es decir:
Running Total =
CALCULATE(
SUM(Movements[Total]),
FILTER(
Calendar,
Fecha del calendario anterior al último día del contexto actual Y
Año del calendario igual al año del contexto actual
)
)
Llevando los campos y funciones reales al pseudo-código anterior tenemos:
Running Total =
CALCULATE(
SUM(Movements[Total]),
FILTER(
ALL('Calendar'),
'Calendar'[Date] <= MAX('Calendar'[Date]) &&
'Calendar'[Año] = MAX('Calendar'[Año]
)
)
)
Debemos asegurarnos de que la tabla Calendar no está siendo filtrada, por lo que se aplica la función <a href="/es/dax/function/all">ALL</a> (de otro modo se contextualizaría y no nos permitiría siempre extraer el período transcurrido desde principio de año).
', 'es') (Line: 118)
Drupal\filter\Element\ProcessedText::preRenderText(Array)
call_user_func_array(Array, Array) (Line: 101)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88)
__TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 46)
__TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 43)
__TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110)
__TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, ) (Line: 242)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
- Deprecated function: Creation of dynamic property Drupal\mysql\Driver\Database\mysql\Select::$alterTags is deprecated in Drupal\Core\Database\Query\Select->addTag() (line 149 of core/lib/Drupal/Core/Database/Query/Select.php).
Drupal\Core\Database\Query\Select->addTag('entity_query') (Line: 147)
Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80)
Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640)
Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63)
Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', 'd6d9cff4-3b60-4c41-8756-9296b87fb31e') (Line: 124)
Drupal\editor\Plugin\Filter\EditorFileReference->process('La función <a href="/es/dax/function/totalytd">TOTALYTD</a> es fácil de usar y nos permite calcular rápidamente el resultado de una expresión para el período transcurrido entre el 1 de enero y la última fecha del contexto actual, pero en ocasiones nos encontraremos con que necesitamos un mayor control sobre la expresión evaluada. En este escenario vamos a simular la función TOTALYTD utilizando otras funciones que nos permitirían ese control adicional.
Partimos de una tabla denominada Movements donde encontramos movimientos financieros asociados a una fecha (supongamos que se trata de ventas):
Por otro lado, por supuesto, tenemos una tabla conteniendo un calendario (tabla Calendar):
Ambas tablas están relacionadas por el campo de fecha. Para simular la función TOTALYTD queremos calcular el acumulado del campo Movements[Total]<em> </em>desde principio de año (del período involucrado en el contexto actual) hasta la última fecha del "período actual".
La expresión base será la suma del campo Movements[Total], expresión que servirá de primer argumento de la función <a href="/es/dax/function/calculate">CALCULATE</a>, a la que deberemos añadir como segundo argumento la modificación del contexto de filtro a aplicar. En pseudo-código, la medida a crear es la siguiente:
Running Total =
CALCULATE(
SUM(Movements[Total]),
Período entre el 1 de enero del año actual hasta el último día del período actual
)
Para el cálculo del período en cuestión (entre el 1 de enero del año correspondiente y el último día del contexto actual) podemos recurrir a filtrar la tabla Calendar con la función <a href="/es/dax/function/filter">FILTER</a> de forma que, dado un contexto actual, seleccione aquellos registros del calendario que involucren las fechas de interés. Es decir, nuestro pseudo-código quedaría así:
Running Total =
CALCULATE(
SUM(Movements[Total]),
FILTER(
Calendar,
Período entre el 1 de enero del año actual hasta el último día del período actual
)
)
Con la función <a href="/es/dax/function/max">MAX</a> aplicada al calendario podemos calcular tanto el último día del contexto actual (aplicando la función al campo Date) como el año siendo considerado (aplicando la función al campo Año), por lo que para extraer el período de interés podríamos imponer dos condiciones:
<ol><li>Que la fecha del calendario sea inferior al último día del contexto actual</li>
<li>Que el año del calendario sea igual al año del contexto actual</li>
</ol>Es decir:
Running Total =
CALCULATE(
SUM(Movements[Total]),
FILTER(
Calendar,
Fecha del calendario anterior al último día del contexto actual Y
Año del calendario igual al año del contexto actual
)
)
Llevando los campos y funciones reales al pseudo-código anterior tenemos:
Running Total =
CALCULATE(
SUM(Movements[Total]),
FILTER(
ALL('Calendar'),
'Calendar'[Date] <= MAX('Calendar'[Date]) &&
'Calendar'[Año] = MAX('Calendar'[Año]
)
)
)
Debemos asegurarnos de que la tabla Calendar no está siendo filtrada, por lo que se aplica la función <a href="/es/dax/function/all">ALL</a> (de otro modo se contextualizaría y no nos permitiría siempre extraer el período transcurrido desde principio de año).
', 'es') (Line: 118)
Drupal\filter\Element\ProcessedText::preRenderText(Array)
call_user_func_array(Array, Array) (Line: 101)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88)
__TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 46)
__TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 43)
__TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110)
__TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, ) (Line: 242)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
- Deprecated function: Creation of dynamic property Drupal\mysql\Driver\Database\mysql\Select::$alterMetaData is deprecated in Drupal\Core\Database\Query\Select->addMetaData() (line 178 of core/lib/Drupal/Core/Database/Query/Select.php).
Drupal\Core\Database\Query\Select->addMetaData('entity_type', 'file') (Line: 115)
Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80)
Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640)
Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63)
Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', '3d5973de-fbb6-46fc-a7b3-2723117843eb') (Line: 95)
Drupal\editor\Plugin\Filter\EditorFileReference->process('La función <a href="/es/dax/function/totalytd">TOTALYTD</a> es fácil de usar y nos permite calcular rápidamente el resultado de una expresión para el período transcurrido entre el 1 de enero y la última fecha del contexto actual, pero en ocasiones nos encontraremos con que necesitamos un mayor control sobre la expresión evaluada. En este escenario vamos a simular la función TOTALYTD utilizando otras funciones que nos permitirían ese control adicional.
Partimos de una tabla denominada Movements donde encontramos movimientos financieros asociados a una fecha (supongamos que se trata de ventas):
Por otro lado, por supuesto, tenemos una tabla conteniendo un calendario (tabla Calendar):
Ambas tablas están relacionadas por el campo de fecha. Para simular la función TOTALYTD queremos calcular el acumulado del campo Movements[Total]<em> </em>desde principio de año (del período involucrado en el contexto actual) hasta la última fecha del "período actual".
La expresión base será la suma del campo Movements[Total], expresión que servirá de primer argumento de la función <a href="/es/dax/function/calculate">CALCULATE</a>, a la que deberemos añadir como segundo argumento la modificación del contexto de filtro a aplicar. En pseudo-código, la medida a crear es la siguiente:
Running Total =
CALCULATE(
SUM(Movements[Total]),
Período entre el 1 de enero del año actual hasta el último día del período actual
)
Para el cálculo del período en cuestión (entre el 1 de enero del año correspondiente y el último día del contexto actual) podemos recurrir a filtrar la tabla Calendar con la función <a href="/es/dax/function/filter">FILTER</a> de forma que, dado un contexto actual, seleccione aquellos registros del calendario que involucren las fechas de interés. Es decir, nuestro pseudo-código quedaría así:
Running Total =
CALCULATE(
SUM(Movements[Total]),
FILTER(
Calendar,
Período entre el 1 de enero del año actual hasta el último día del período actual
)
)
Con la función <a href="/es/dax/function/max">MAX</a> aplicada al calendario podemos calcular tanto el último día del contexto actual (aplicando la función al campo Date) como el año siendo considerado (aplicando la función al campo Año), por lo que para extraer el período de interés podríamos imponer dos condiciones:
<ol><li>Que la fecha del calendario sea inferior al último día del contexto actual</li>
<li>Que el año del calendario sea igual al año del contexto actual</li>
</ol>Es decir:
Running Total =
CALCULATE(
SUM(Movements[Total]),
FILTER(
Calendar,
Fecha del calendario anterior al último día del contexto actual Y
Año del calendario igual al año del contexto actual
)
)
Llevando los campos y funciones reales al pseudo-código anterior tenemos:
Running Total =
CALCULATE(
SUM(Movements[Total]),
FILTER(
ALL('Calendar'),
'Calendar'[Date] <= MAX('Calendar'[Date]) &&
'Calendar'[Año] = MAX('Calendar'[Año]
)
)
)
Debemos asegurarnos de que la tabla Calendar no está siendo filtrada, por lo que se aplica la función <a href="/es/dax/function/all">ALL</a> (de otro modo se contextualizaría y no nos permitiría siempre extraer el período transcurrido desde principio de año).
', 'es') (Line: 118)
Drupal\filter\Element\ProcessedText::preRenderText(Array)
call_user_func_array(Array, Array) (Line: 101)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88)
__TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 46)
__TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 43)
__TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110)
__TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, ) (Line: 242)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
- Deprecated function: Creation of dynamic property Drupal\mysql\Driver\Database\mysql\Select::$alterTags is deprecated in Drupal\Core\Database\Query\Select->addTag() (line 149 of core/lib/Drupal/Core/Database/Query/Select.php).
Drupal\Core\Database\Query\Select->addTag('entity_query') (Line: 147)
Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80)
Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640)
Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63)
Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', '3d5973de-fbb6-46fc-a7b3-2723117843eb') (Line: 95)
Drupal\editor\Plugin\Filter\EditorFileReference->process('La función <a href="/es/dax/function/totalytd">TOTALYTD</a> es fácil de usar y nos permite calcular rápidamente el resultado de una expresión para el período transcurrido entre el 1 de enero y la última fecha del contexto actual, pero en ocasiones nos encontraremos con que necesitamos un mayor control sobre la expresión evaluada. En este escenario vamos a simular la función TOTALYTD utilizando otras funciones que nos permitirían ese control adicional.
Partimos de una tabla denominada Movements donde encontramos movimientos financieros asociados a una fecha (supongamos que se trata de ventas):
Por otro lado, por supuesto, tenemos una tabla conteniendo un calendario (tabla Calendar):
Ambas tablas están relacionadas por el campo de fecha. Para simular la función TOTALYTD queremos calcular el acumulado del campo Movements[Total]<em> </em>desde principio de año (del período involucrado en el contexto actual) hasta la última fecha del "período actual".
La expresión base será la suma del campo Movements[Total], expresión que servirá de primer argumento de la función <a href="/es/dax/function/calculate">CALCULATE</a>, a la que deberemos añadir como segundo argumento la modificación del contexto de filtro a aplicar. En pseudo-código, la medida a crear es la siguiente:
Running Total =
CALCULATE(
SUM(Movements[Total]),
Período entre el 1 de enero del año actual hasta el último día del período actual
)
Para el cálculo del período en cuestión (entre el 1 de enero del año correspondiente y el último día del contexto actual) podemos recurrir a filtrar la tabla Calendar con la función <a href="/es/dax/function/filter">FILTER</a> de forma que, dado un contexto actual, seleccione aquellos registros del calendario que involucren las fechas de interés. Es decir, nuestro pseudo-código quedaría así:
Running Total =
CALCULATE(
SUM(Movements[Total]),
FILTER(
Calendar,
Período entre el 1 de enero del año actual hasta el último día del período actual
)
)
Con la función <a href="/es/dax/function/max">MAX</a> aplicada al calendario podemos calcular tanto el último día del contexto actual (aplicando la función al campo Date) como el año siendo considerado (aplicando la función al campo Año), por lo que para extraer el período de interés podríamos imponer dos condiciones:
<ol><li>Que la fecha del calendario sea inferior al último día del contexto actual</li>
<li>Que el año del calendario sea igual al año del contexto actual</li>
</ol>Es decir:
Running Total =
CALCULATE(
SUM(Movements[Total]),
FILTER(
Calendar,
Fecha del calendario anterior al último día del contexto actual Y
Año del calendario igual al año del contexto actual
)
)
Llevando los campos y funciones reales al pseudo-código anterior tenemos:
Running Total =
CALCULATE(
SUM(Movements[Total]),
FILTER(
ALL('Calendar'),
'Calendar'[Date] <= MAX('Calendar'[Date]) &&
'Calendar'[Año] = MAX('Calendar'[Año]
)
)
)
Debemos asegurarnos de que la tabla Calendar no está siendo filtrada, por lo que se aplica la función <a href="/es/dax/function/all">ALL</a> (de otro modo se contextualizaría y no nos permitiría siempre extraer el período transcurrido desde principio de año).
', 'es') (Line: 118)
Drupal\filter\Element\ProcessedText::preRenderText(Array)
call_user_func_array(Array, Array) (Line: 101)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88)
__TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 46)
__TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 43)
__TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110)
__TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, ) (Line: 242)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
- Deprecated function: Creation of dynamic property Drupal\mysql\Driver\Database\mysql\Select::$alterTags is deprecated in Drupal\Core\Database\Query\Select->addTag() (line 149 of core/lib/Drupal/Core/Database/Query/Select.php).
Drupal\Core\Database\Query\Select->addTag('file_load_multiple') (Line: 696)
Drupal\Core\Entity\Sql\SqlContentEntityStorage->buildQuery(Array) (Line: 422)
Drupal\Core\Entity\Sql\SqlContentEntityStorage->getFromStorage(Array) (Line: 393)
Drupal\Core\Entity\Sql\SqlContentEntityStorage->doLoadMultiple(Array) (Line: 346)
Drupal\Core\Entity\EntityStorageBase->loadMultiple(Array) (Line: 641)
Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63)
Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', '3d5973de-fbb6-46fc-a7b3-2723117843eb') (Line: 95)
Drupal\editor\Plugin\Filter\EditorFileReference->process('La función <a href="/es/dax/function/totalytd">TOTALYTD</a> es fácil de usar y nos permite calcular rápidamente el resultado de una expresión para el período transcurrido entre el 1 de enero y la última fecha del contexto actual, pero en ocasiones nos encontraremos con que necesitamos un mayor control sobre la expresión evaluada. En este escenario vamos a simular la función TOTALYTD utilizando otras funciones que nos permitirían ese control adicional.
Partimos de una tabla denominada Movements donde encontramos movimientos financieros asociados a una fecha (supongamos que se trata de ventas):
Por otro lado, por supuesto, tenemos una tabla conteniendo un calendario (tabla Calendar):
Ambas tablas están relacionadas por el campo de fecha. Para simular la función TOTALYTD queremos calcular el acumulado del campo Movements[Total]<em> </em>desde principio de año (del período involucrado en el contexto actual) hasta la última fecha del "período actual".
La expresión base será la suma del campo Movements[Total], expresión que servirá de primer argumento de la función <a href="/es/dax/function/calculate">CALCULATE</a>, a la que deberemos añadir como segundo argumento la modificación del contexto de filtro a aplicar. En pseudo-código, la medida a crear es la siguiente:
Running Total =
CALCULATE(
SUM(Movements[Total]),
Período entre el 1 de enero del año actual hasta el último día del período actual
)
Para el cálculo del período en cuestión (entre el 1 de enero del año correspondiente y el último día del contexto actual) podemos recurrir a filtrar la tabla Calendar con la función <a href="/es/dax/function/filter">FILTER</a> de forma que, dado un contexto actual, seleccione aquellos registros del calendario que involucren las fechas de interés. Es decir, nuestro pseudo-código quedaría así:
Running Total =
CALCULATE(
SUM(Movements[Total]),
FILTER(
Calendar,
Período entre el 1 de enero del año actual hasta el último día del período actual
)
)
Con la función <a href="/es/dax/function/max">MAX</a> aplicada al calendario podemos calcular tanto el último día del contexto actual (aplicando la función al campo Date) como el año siendo considerado (aplicando la función al campo Año), por lo que para extraer el período de interés podríamos imponer dos condiciones:
<ol><li>Que la fecha del calendario sea inferior al último día del contexto actual</li>
<li>Que el año del calendario sea igual al año del contexto actual</li>
</ol>Es decir:
Running Total =
CALCULATE(
SUM(Movements[Total]),
FILTER(
Calendar,
Fecha del calendario anterior al último día del contexto actual Y
Año del calendario igual al año del contexto actual
)
)
Llevando los campos y funciones reales al pseudo-código anterior tenemos:
Running Total =
CALCULATE(
SUM(Movements[Total]),
FILTER(
ALL('Calendar'),
'Calendar'[Date] <= MAX('Calendar'[Date]) &&
'Calendar'[Año] = MAX('Calendar'[Año]
)
)
)
Debemos asegurarnos de que la tabla Calendar no está siendo filtrada, por lo que se aplica la función <a href="/es/dax/function/all">ALL</a> (de otro modo se contextualizaría y no nos permitiría siempre extraer el período transcurrido desde principio de año).
', 'es') (Line: 118)
Drupal\filter\Element\ProcessedText::preRenderText(Array)
call_user_func_array(Array, Array) (Line: 101)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88)
__TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 46)
__TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 43)
__TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110)
__TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, ) (Line: 242)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
- Deprecated function: Creation of dynamic property Drupal\mysql\Driver\Database\mysql\Select::$alterMetaData is deprecated in Drupal\Core\Database\Query\Select->addMetaData() (line 178 of core/lib/Drupal/Core/Database/Query/Select.php).
Drupal\Core\Database\Query\Select->addMetaData('entity_type', 'file') (Line: 115)
Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80)
Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640)
Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63)
Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', '3d5973de-fbb6-46fc-a7b3-2723117843eb') (Line: 124)
Drupal\editor\Plugin\Filter\EditorFileReference->process('La función <a href="/es/dax/function/totalytd">TOTALYTD</a> es fácil de usar y nos permite calcular rápidamente el resultado de una expresión para el período transcurrido entre el 1 de enero y la última fecha del contexto actual, pero en ocasiones nos encontraremos con que necesitamos un mayor control sobre la expresión evaluada. En este escenario vamos a simular la función TOTALYTD utilizando otras funciones que nos permitirían ese control adicional.
Partimos de una tabla denominada Movements donde encontramos movimientos financieros asociados a una fecha (supongamos que se trata de ventas):
Por otro lado, por supuesto, tenemos una tabla conteniendo un calendario (tabla Calendar):
Ambas tablas están relacionadas por el campo de fecha. Para simular la función TOTALYTD queremos calcular el acumulado del campo Movements[Total]<em> </em>desde principio de año (del período involucrado en el contexto actual) hasta la última fecha del "período actual".
La expresión base será la suma del campo Movements[Total], expresión que servirá de primer argumento de la función <a href="/es/dax/function/calculate">CALCULATE</a>, a la que deberemos añadir como segundo argumento la modificación del contexto de filtro a aplicar. En pseudo-código, la medida a crear es la siguiente:
Running Total =
CALCULATE(
SUM(Movements[Total]),
Período entre el 1 de enero del año actual hasta el último día del período actual
)
Para el cálculo del período en cuestión (entre el 1 de enero del año correspondiente y el último día del contexto actual) podemos recurrir a filtrar la tabla Calendar con la función <a href="/es/dax/function/filter">FILTER</a> de forma que, dado un contexto actual, seleccione aquellos registros del calendario que involucren las fechas de interés. Es decir, nuestro pseudo-código quedaría así:
Running Total =
CALCULATE(
SUM(Movements[Total]),
FILTER(
Calendar,
Período entre el 1 de enero del año actual hasta el último día del período actual
)
)
Con la función <a href="/es/dax/function/max">MAX</a> aplicada al calendario podemos calcular tanto el último día del contexto actual (aplicando la función al campo Date) como el año siendo considerado (aplicando la función al campo Año), por lo que para extraer el período de interés podríamos imponer dos condiciones:
<ol><li>Que la fecha del calendario sea inferior al último día del contexto actual</li>
<li>Que el año del calendario sea igual al año del contexto actual</li>
</ol>Es decir:
Running Total =
CALCULATE(
SUM(Movements[Total]),
FILTER(
Calendar,
Fecha del calendario anterior al último día del contexto actual Y
Año del calendario igual al año del contexto actual
)
)
Llevando los campos y funciones reales al pseudo-código anterior tenemos:
Running Total =
CALCULATE(
SUM(Movements[Total]),
FILTER(
ALL('Calendar'),
'Calendar'[Date] <= MAX('Calendar'[Date]) &&
'Calendar'[Año] = MAX('Calendar'[Año]
)
)
)
Debemos asegurarnos de que la tabla Calendar no está siendo filtrada, por lo que se aplica la función <a href="/es/dax/function/all">ALL</a> (de otro modo se contextualizaría y no nos permitiría siempre extraer el período transcurrido desde principio de año).
', 'es') (Line: 118)
Drupal\filter\Element\ProcessedText::preRenderText(Array)
call_user_func_array(Array, Array) (Line: 101)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88)
__TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 46)
__TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 43)
__TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110)
__TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, ) (Line: 242)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
- Deprecated function: Creation of dynamic property Drupal\mysql\Driver\Database\mysql\Select::$alterTags is deprecated in Drupal\Core\Database\Query\Select->addTag() (line 149 of core/lib/Drupal/Core/Database/Query/Select.php).
Drupal\Core\Database\Query\Select->addTag('entity_query') (Line: 147)
Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80)
Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640)
Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63)
Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', '3d5973de-fbb6-46fc-a7b3-2723117843eb') (Line: 124)
Drupal\editor\Plugin\Filter\EditorFileReference->process('La función <a href="/es/dax/function/totalytd">TOTALYTD</a> es fácil de usar y nos permite calcular rápidamente el resultado de una expresión para el período transcurrido entre el 1 de enero y la última fecha del contexto actual, pero en ocasiones nos encontraremos con que necesitamos un mayor control sobre la expresión evaluada. En este escenario vamos a simular la función TOTALYTD utilizando otras funciones que nos permitirían ese control adicional.
Partimos de una tabla denominada Movements donde encontramos movimientos financieros asociados a una fecha (supongamos que se trata de ventas):
Por otro lado, por supuesto, tenemos una tabla conteniendo un calendario (tabla Calendar):
Ambas tablas están relacionadas por el campo de fecha. Para simular la función TOTALYTD queremos calcular el acumulado del campo Movements[Total]<em> </em>desde principio de año (del período involucrado en el contexto actual) hasta la última fecha del "período actual".
La expresión base será la suma del campo Movements[Total], expresión que servirá de primer argumento de la función <a href="/es/dax/function/calculate">CALCULATE</a>, a la que deberemos añadir como segundo argumento la modificación del contexto de filtro a aplicar. En pseudo-código, la medida a crear es la siguiente:
Running Total =
CALCULATE(
SUM(Movements[Total]),
Período entre el 1 de enero del año actual hasta el último día del período actual
)
Para el cálculo del período en cuestión (entre el 1 de enero del año correspondiente y el último día del contexto actual) podemos recurrir a filtrar la tabla Calendar con la función <a href="/es/dax/function/filter">FILTER</a> de forma que, dado un contexto actual, seleccione aquellos registros del calendario que involucren las fechas de interés. Es decir, nuestro pseudo-código quedaría así:
Running Total =
CALCULATE(
SUM(Movements[Total]),
FILTER(
Calendar,
Período entre el 1 de enero del año actual hasta el último día del período actual
)
)
Con la función <a href="/es/dax/function/max">MAX</a> aplicada al calendario podemos calcular tanto el último día del contexto actual (aplicando la función al campo Date) como el año siendo considerado (aplicando la función al campo Año), por lo que para extraer el período de interés podríamos imponer dos condiciones:
<ol><li>Que la fecha del calendario sea inferior al último día del contexto actual</li>
<li>Que el año del calendario sea igual al año del contexto actual</li>
</ol>Es decir:
Running Total =
CALCULATE(
SUM(Movements[Total]),
FILTER(
Calendar,
Fecha del calendario anterior al último día del contexto actual Y
Año del calendario igual al año del contexto actual
)
)
Llevando los campos y funciones reales al pseudo-código anterior tenemos:
Running Total =
CALCULATE(
SUM(Movements[Total]),
FILTER(
ALL('Calendar'),
'Calendar'[Date] <= MAX('Calendar'[Date]) &&
'Calendar'[Año] = MAX('Calendar'[Año]
)
)
)
Debemos asegurarnos de que la tabla Calendar no está siendo filtrada, por lo que se aplica la función <a href="/es/dax/function/all">ALL</a> (de otro modo se contextualizaría y no nos permitiría siempre extraer el período transcurrido desde principio de año).
', 'es') (Line: 118)
Drupal\filter\Element\ProcessedText::preRenderText(Array)
call_user_func_array(Array, Array) (Line: 101)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88)
__TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 46)
__TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 43)
__TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110)
__TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, ) (Line: 242)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
- Deprecated function: Creation of dynamic property Drupal\mysql\Driver\Database\mysql\Select::$alterMetaData is deprecated in Drupal\Core\Database\Query\Select->addMetaData() (line 178 of core/lib/Drupal/Core/Database/Query/Select.php).
Drupal\Core\Database\Query\Select->addMetaData('entity_type', 'file') (Line: 115)
Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80)
Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640)
Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63)
Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', '643bf1fb-f9bd-43ed-b301-af93081e9895') (Line: 95)
Drupal\editor\Plugin\Filter\EditorFileReference->process('La función <a href="/es/dax/function/totalytd">TOTALYTD</a> es fácil de usar y nos permite calcular rápidamente el resultado de una expresión para el período transcurrido entre el 1 de enero y la última fecha del contexto actual, pero en ocasiones nos encontraremos con que necesitamos un mayor control sobre la expresión evaluada. En este escenario vamos a simular la función TOTALYTD utilizando otras funciones que nos permitirían ese control adicional.
Partimos de una tabla denominada Movements donde encontramos movimientos financieros asociados a una fecha (supongamos que se trata de ventas):
Por otro lado, por supuesto, tenemos una tabla conteniendo un calendario (tabla Calendar):
Ambas tablas están relacionadas por el campo de fecha. Para simular la función TOTALYTD queremos calcular el acumulado del campo Movements[Total]<em> </em>desde principio de año (del período involucrado en el contexto actual) hasta la última fecha del "período actual".
La expresión base será la suma del campo Movements[Total], expresión que servirá de primer argumento de la función <a href="/es/dax/function/calculate">CALCULATE</a>, a la que deberemos añadir como segundo argumento la modificación del contexto de filtro a aplicar. En pseudo-código, la medida a crear es la siguiente:
Running Total =
CALCULATE(
SUM(Movements[Total]),
Período entre el 1 de enero del año actual hasta el último día del período actual
)
Para el cálculo del período en cuestión (entre el 1 de enero del año correspondiente y el último día del contexto actual) podemos recurrir a filtrar la tabla Calendar con la función <a href="/es/dax/function/filter">FILTER</a> de forma que, dado un contexto actual, seleccione aquellos registros del calendario que involucren las fechas de interés. Es decir, nuestro pseudo-código quedaría así:
Running Total =
CALCULATE(
SUM(Movements[Total]),
FILTER(
Calendar,
Período entre el 1 de enero del año actual hasta el último día del período actual
)
)
Con la función <a href="/es/dax/function/max">MAX</a> aplicada al calendario podemos calcular tanto el último día del contexto actual (aplicando la función al campo Date) como el año siendo considerado (aplicando la función al campo Año), por lo que para extraer el período de interés podríamos imponer dos condiciones:
<ol><li>Que la fecha del calendario sea inferior al último día del contexto actual</li>
<li>Que el año del calendario sea igual al año del contexto actual</li>
</ol>Es decir:
Running Total =
CALCULATE(
SUM(Movements[Total]),
FILTER(
Calendar,
Fecha del calendario anterior al último día del contexto actual Y
Año del calendario igual al año del contexto actual
)
)
Llevando los campos y funciones reales al pseudo-código anterior tenemos:
Running Total =
CALCULATE(
SUM(Movements[Total]),
FILTER(
ALL('Calendar'),
'Calendar'[Date] <= MAX('Calendar'[Date]) &&
'Calendar'[Año] = MAX('Calendar'[Año]
)
)
)
Debemos asegurarnos de que la tabla Calendar no está siendo filtrada, por lo que se aplica la función <a href="/es/dax/function/all">ALL</a> (de otro modo se contextualizaría y no nos permitiría siempre extraer el período transcurrido desde principio de año).
', 'es') (Line: 118)
Drupal\filter\Element\ProcessedText::preRenderText(Array)
call_user_func_array(Array, Array) (Line: 101)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88)
__TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 46)
__TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 43)
__TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110)
__TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, ) (Line: 242)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
- Deprecated function: Creation of dynamic property Drupal\mysql\Driver\Database\mysql\Select::$alterTags is deprecated in Drupal\Core\Database\Query\Select->addTag() (line 149 of core/lib/Drupal/Core/Database/Query/Select.php).
Drupal\Core\Database\Query\Select->addTag('entity_query') (Line: 147)
Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80)
Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640)
Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63)
Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', '643bf1fb-f9bd-43ed-b301-af93081e9895') (Line: 95)
Drupal\editor\Plugin\Filter\EditorFileReference->process('La función <a href="/es/dax/function/totalytd">TOTALYTD</a> es fácil de usar y nos permite calcular rápidamente el resultado de una expresión para el período transcurrido entre el 1 de enero y la última fecha del contexto actual, pero en ocasiones nos encontraremos con que necesitamos un mayor control sobre la expresión evaluada. En este escenario vamos a simular la función TOTALYTD utilizando otras funciones que nos permitirían ese control adicional.
Partimos de una tabla denominada Movements donde encontramos movimientos financieros asociados a una fecha (supongamos que se trata de ventas):
Por otro lado, por supuesto, tenemos una tabla conteniendo un calendario (tabla Calendar):
Ambas tablas están relacionadas por el campo de fecha. Para simular la función TOTALYTD queremos calcular el acumulado del campo Movements[Total]<em> </em>desde principio de año (del período involucrado en el contexto actual) hasta la última fecha del "período actual".
La expresión base será la suma del campo Movements[Total], expresión que servirá de primer argumento de la función <a href="/es/dax/function/calculate">CALCULATE</a>, a la que deberemos añadir como segundo argumento la modificación del contexto de filtro a aplicar. En pseudo-código, la medida a crear es la siguiente:
Running Total =
CALCULATE(
SUM(Movements[Total]),
Período entre el 1 de enero del año actual hasta el último día del período actual
)
Para el cálculo del período en cuestión (entre el 1 de enero del año correspondiente y el último día del contexto actual) podemos recurrir a filtrar la tabla Calendar con la función <a href="/es/dax/function/filter">FILTER</a> de forma que, dado un contexto actual, seleccione aquellos registros del calendario que involucren las fechas de interés. Es decir, nuestro pseudo-código quedaría así:
Running Total =
CALCULATE(
SUM(Movements[Total]),
FILTER(
Calendar,
Período entre el 1 de enero del año actual hasta el último día del período actual
)
)
Con la función <a href="/es/dax/function/max">MAX</a> aplicada al calendario podemos calcular tanto el último día del contexto actual (aplicando la función al campo Date) como el año siendo considerado (aplicando la función al campo Año), por lo que para extraer el período de interés podríamos imponer dos condiciones:
<ol><li>Que la fecha del calendario sea inferior al último día del contexto actual</li>
<li>Que el año del calendario sea igual al año del contexto actual</li>
</ol>Es decir:
Running Total =
CALCULATE(
SUM(Movements[Total]),
FILTER(
Calendar,
Fecha del calendario anterior al último día del contexto actual Y
Año del calendario igual al año del contexto actual
)
)
Llevando los campos y funciones reales al pseudo-código anterior tenemos:
Running Total =
CALCULATE(
SUM(Movements[Total]),
FILTER(
ALL('Calendar'),
'Calendar'[Date] <= MAX('Calendar'[Date]) &&
'Calendar'[Año] = MAX('Calendar'[Año]
)
)
)
Debemos asegurarnos de que la tabla Calendar no está siendo filtrada, por lo que se aplica la función <a href="/es/dax/function/all">ALL</a> (de otro modo se contextualizaría y no nos permitiría siempre extraer el período transcurrido desde principio de año).
', 'es') (Line: 118)
Drupal\filter\Element\ProcessedText::preRenderText(Array)
call_user_func_array(Array, Array) (Line: 101)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88)
__TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 46)
__TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 43)
__TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110)
__TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, ) (Line: 242)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
- Deprecated function: Creation of dynamic property Drupal\mysql\Driver\Database\mysql\Select::$alterTags is deprecated in Drupal\Core\Database\Query\Select->addTag() (line 149 of core/lib/Drupal/Core/Database/Query/Select.php).
Drupal\Core\Database\Query\Select->addTag('file_load_multiple') (Line: 696)
Drupal\Core\Entity\Sql\SqlContentEntityStorage->buildQuery(Array) (Line: 422)
Drupal\Core\Entity\Sql\SqlContentEntityStorage->getFromStorage(Array) (Line: 393)
Drupal\Core\Entity\Sql\SqlContentEntityStorage->doLoadMultiple(Array) (Line: 346)
Drupal\Core\Entity\EntityStorageBase->loadMultiple(Array) (Line: 641)
Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63)
Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', '643bf1fb-f9bd-43ed-b301-af93081e9895') (Line: 95)
Drupal\editor\Plugin\Filter\EditorFileReference->process('La función <a href="/es/dax/function/totalytd">TOTALYTD</a> es fácil de usar y nos permite calcular rápidamente el resultado de una expresión para el período transcurrido entre el 1 de enero y la última fecha del contexto actual, pero en ocasiones nos encontraremos con que necesitamos un mayor control sobre la expresión evaluada. En este escenario vamos a simular la función TOTALYTD utilizando otras funciones que nos permitirían ese control adicional.
Partimos de una tabla denominada Movements donde encontramos movimientos financieros asociados a una fecha (supongamos que se trata de ventas):
Por otro lado, por supuesto, tenemos una tabla conteniendo un calendario (tabla Calendar):
Ambas tablas están relacionadas por el campo de fecha. Para simular la función TOTALYTD queremos calcular el acumulado del campo Movements[Total]<em> </em>desde principio de año (del período involucrado en el contexto actual) hasta la última fecha del "período actual".
La expresión base será la suma del campo Movements[Total], expresión que servirá de primer argumento de la función <a href="/es/dax/function/calculate">CALCULATE</a>, a la que deberemos añadir como segundo argumento la modificación del contexto de filtro a aplicar. En pseudo-código, la medida a crear es la siguiente:
Running Total =
CALCULATE(
SUM(Movements[Total]),
Período entre el 1 de enero del año actual hasta el último día del período actual
)
Para el cálculo del período en cuestión (entre el 1 de enero del año correspondiente y el último día del contexto actual) podemos recurrir a filtrar la tabla Calendar con la función <a href="/es/dax/function/filter">FILTER</a> de forma que, dado un contexto actual, seleccione aquellos registros del calendario que involucren las fechas de interés. Es decir, nuestro pseudo-código quedaría así:
Running Total =
CALCULATE(
SUM(Movements[Total]),
FILTER(
Calendar,
Período entre el 1 de enero del año actual hasta el último día del período actual
)
)
Con la función <a href="/es/dax/function/max">MAX</a> aplicada al calendario podemos calcular tanto el último día del contexto actual (aplicando la función al campo Date) como el año siendo considerado (aplicando la función al campo Año), por lo que para extraer el período de interés podríamos imponer dos condiciones:
<ol><li>Que la fecha del calendario sea inferior al último día del contexto actual</li>
<li>Que el año del calendario sea igual al año del contexto actual</li>
</ol>Es decir:
Running Total =
CALCULATE(
SUM(Movements[Total]),
FILTER(
Calendar,
Fecha del calendario anterior al último día del contexto actual Y
Año del calendario igual al año del contexto actual
)
)
Llevando los campos y funciones reales al pseudo-código anterior tenemos:
Running Total =
CALCULATE(
SUM(Movements[Total]),
FILTER(
ALL('Calendar'),
'Calendar'[Date] <= MAX('Calendar'[Date]) &&
'Calendar'[Año] = MAX('Calendar'[Año]
)
)
)
Debemos asegurarnos de que la tabla Calendar no está siendo filtrada, por lo que se aplica la función <a href="/es/dax/function/all">ALL</a> (de otro modo se contextualizaría y no nos permitiría siempre extraer el período transcurrido desde principio de año).
', 'es') (Line: 118)
Drupal\filter\Element\ProcessedText::preRenderText(Array)
call_user_func_array(Array, Array) (Line: 101)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88)
__TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 46)
__TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 43)
__TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110)
__TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, ) (Line: 242)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
- Deprecated function: Creation of dynamic property Drupal\mysql\Driver\Database\mysql\Select::$alterMetaData is deprecated in Drupal\Core\Database\Query\Select->addMetaData() (line 178 of core/lib/Drupal/Core/Database/Query/Select.php).
Drupal\Core\Database\Query\Select->addMetaData('entity_type', 'file') (Line: 115)
Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80)
Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640)
Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63)
Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', '643bf1fb-f9bd-43ed-b301-af93081e9895') (Line: 124)
Drupal\editor\Plugin\Filter\EditorFileReference->process('La función <a href="/es/dax/function/totalytd">TOTALYTD</a> es fácil de usar y nos permite calcular rápidamente el resultado de una expresión para el período transcurrido entre el 1 de enero y la última fecha del contexto actual, pero en ocasiones nos encontraremos con que necesitamos un mayor control sobre la expresión evaluada. En este escenario vamos a simular la función TOTALYTD utilizando otras funciones que nos permitirían ese control adicional.
Partimos de una tabla denominada Movements donde encontramos movimientos financieros asociados a una fecha (supongamos que se trata de ventas):
Por otro lado, por supuesto, tenemos una tabla conteniendo un calendario (tabla Calendar):
Ambas tablas están relacionadas por el campo de fecha. Para simular la función TOTALYTD queremos calcular el acumulado del campo Movements[Total]<em> </em>desde principio de año (del período involucrado en el contexto actual) hasta la última fecha del "período actual".
La expresión base será la suma del campo Movements[Total], expresión que servirá de primer argumento de la función <a href="/es/dax/function/calculate">CALCULATE</a>, a la que deberemos añadir como segundo argumento la modificación del contexto de filtro a aplicar. En pseudo-código, la medida a crear es la siguiente:
Running Total =
CALCULATE(
SUM(Movements[Total]),
Período entre el 1 de enero del año actual hasta el último día del período actual
)
Para el cálculo del período en cuestión (entre el 1 de enero del año correspondiente y el último día del contexto actual) podemos recurrir a filtrar la tabla Calendar con la función <a href="/es/dax/function/filter">FILTER</a> de forma que, dado un contexto actual, seleccione aquellos registros del calendario que involucren las fechas de interés. Es decir, nuestro pseudo-código quedaría así:
Running Total =
CALCULATE(
SUM(Movements[Total]),
FILTER(
Calendar,
Período entre el 1 de enero del año actual hasta el último día del período actual
)
)
Con la función <a href="/es/dax/function/max">MAX</a> aplicada al calendario podemos calcular tanto el último día del contexto actual (aplicando la función al campo Date) como el año siendo considerado (aplicando la función al campo Año), por lo que para extraer el período de interés podríamos imponer dos condiciones:
<ol><li>Que la fecha del calendario sea inferior al último día del contexto actual</li>
<li>Que el año del calendario sea igual al año del contexto actual</li>
</ol>Es decir:
Running Total =
CALCULATE(
SUM(Movements[Total]),
FILTER(
Calendar,
Fecha del calendario anterior al último día del contexto actual Y
Año del calendario igual al año del contexto actual
)
)
Llevando los campos y funciones reales al pseudo-código anterior tenemos:
Running Total =
CALCULATE(
SUM(Movements[Total]),
FILTER(
ALL('Calendar'),
'Calendar'[Date] <= MAX('Calendar'[Date]) &&
'Calendar'[Año] = MAX('Calendar'[Año]
)
)
)
Debemos asegurarnos de que la tabla Calendar no está siendo filtrada, por lo que se aplica la función <a href="/es/dax/function/all">ALL</a> (de otro modo se contextualizaría y no nos permitiría siempre extraer el período transcurrido desde principio de año).
', 'es') (Line: 118)
Drupal\filter\Element\ProcessedText::preRenderText(Array)
call_user_func_array(Array, Array) (Line: 101)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88)
__TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 46)
__TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 43)
__TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110)
__TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, ) (Line: 242)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
- Deprecated function: Creation of dynamic property Drupal\mysql\Driver\Database\mysql\Select::$alterTags is deprecated in Drupal\Core\Database\Query\Select->addTag() (line 149 of core/lib/Drupal/Core/Database/Query/Select.php).
Drupal\Core\Database\Query\Select->addTag('entity_query') (Line: 147)
Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80)
Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640)
Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63)
Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', '643bf1fb-f9bd-43ed-b301-af93081e9895') (Line: 124)
Drupal\editor\Plugin\Filter\EditorFileReference->process('La función <a href="/es/dax/function/totalytd">TOTALYTD</a> es fácil de usar y nos permite calcular rápidamente el resultado de una expresión para el período transcurrido entre el 1 de enero y la última fecha del contexto actual, pero en ocasiones nos encontraremos con que necesitamos un mayor control sobre la expresión evaluada. En este escenario vamos a simular la función TOTALYTD utilizando otras funciones que nos permitirían ese control adicional.
Partimos de una tabla denominada Movements donde encontramos movimientos financieros asociados a una fecha (supongamos que se trata de ventas):
Por otro lado, por supuesto, tenemos una tabla conteniendo un calendario (tabla Calendar):
Ambas tablas están relacionadas por el campo de fecha. Para simular la función TOTALYTD queremos calcular el acumulado del campo Movements[Total]<em> </em>desde principio de año (del período involucrado en el contexto actual) hasta la última fecha del "período actual".
La expresión base será la suma del campo Movements[Total], expresión que servirá de primer argumento de la función <a href="/es/dax/function/calculate">CALCULATE</a>, a la que deberemos añadir como segundo argumento la modificación del contexto de filtro a aplicar. En pseudo-código, la medida a crear es la siguiente:
Running Total =
CALCULATE(
SUM(Movements[Total]),
Período entre el 1 de enero del año actual hasta el último día del período actual
)
Para el cálculo del período en cuestión (entre el 1 de enero del año correspondiente y el último día del contexto actual) podemos recurrir a filtrar la tabla Calendar con la función <a href="/es/dax/function/filter">FILTER</a> de forma que, dado un contexto actual, seleccione aquellos registros del calendario que involucren las fechas de interés. Es decir, nuestro pseudo-código quedaría así:
Running Total =
CALCULATE(
SUM(Movements[Total]),
FILTER(
Calendar,
Período entre el 1 de enero del año actual hasta el último día del período actual
)
)
Con la función <a href="/es/dax/function/max">MAX</a> aplicada al calendario podemos calcular tanto el último día del contexto actual (aplicando la función al campo Date) como el año siendo considerado (aplicando la función al campo Año), por lo que para extraer el período de interés podríamos imponer dos condiciones:
<ol><li>Que la fecha del calendario sea inferior al último día del contexto actual</li>
<li>Que el año del calendario sea igual al año del contexto actual</li>
</ol>Es decir:
Running Total =
CALCULATE(
SUM(Movements[Total]),
FILTER(
Calendar,
Fecha del calendario anterior al último día del contexto actual Y
Año del calendario igual al año del contexto actual
)
)
Llevando los campos y funciones reales al pseudo-código anterior tenemos:
Running Total =
CALCULATE(
SUM(Movements[Total]),
FILTER(
ALL('Calendar'),
'Calendar'[Date] <= MAX('Calendar'[Date]) &&
'Calendar'[Año] = MAX('Calendar'[Año]
)
)
)
Debemos asegurarnos de que la tabla Calendar no está siendo filtrada, por lo que se aplica la función <a href="/es/dax/function/all">ALL</a> (de otro modo se contextualizaría y no nos permitiría siempre extraer el período transcurrido desde principio de año).
', 'es') (Line: 118)
Drupal\filter\Element\ProcessedText::preRenderText(Array)
call_user_func_array(Array, Array) (Line: 101)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88)
__TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 46)
__TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 43)
__TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110)
__TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, ) (Line: 242)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
- Deprecated function: Creation of dynamic property Drupal\mysql\Driver\Database\mysql\Select::$alterMetaData is deprecated in Drupal\Core\Database\Query\Select->addMetaData() (line 178 of core/lib/Drupal/Core/Database/Query/Select.php).
Drupal\Core\Database\Query\Select->addMetaData('entity_type', 'file') (Line: 115)
Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80)
Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640)
Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63)
Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', 'insert-max_800_px-26f2094f-6fc5-4d8f-9cc2-da5576c21073') (Line: 95)
Drupal\editor\Plugin\Filter\EditorFileReference->process('En este escenario partimos de la siguiente tabla de datos:
<a class="colorbox insert-colorbox" data-colorbox-gallery="gallery-node" data-insert-class="" data-insert-type="image" href="/sites/default/files/2021-06/dax-0110.jpg"></a>
Obsérvese que en la tabla las fechas se muestran ordenadas (de más antiguas a más modernas) para hacer más sencilla su interpretación, pero tengamos en mente que podría no ser así.
El objetivo es crear una columna calculada que nos indique, para cada fila, cuántas filas de la misma tabla contienen fechas anteriores a la de la fila siendo considerada (teniendo en cuenta, como se ha comentado, que las filas podrían estar no ordenadas según la fecha).
Como queremos añadir una columna calculada, se va a crear por defecto un contexto de fila para cada una de las filas evaluadas. Es decir, para la primera fila (la correspondiente al campo <em>Id</em> 1) se creará un contexto de fila en el que podremos acceder a los valores de sus campos, <em>Id</em> y <em>Date</em>. A partir del valor del campo <em>Date</em> querríamos filtrar la tabla de forma que solo se considerasen las filas con fechas anteriores y contar el número de filas resultantes.
En pseudo código sería algo así:
Number of Previous values =
COUNTROWS(
FILTER(
data,
data[Date] < fecha-de-la-fila-actual
)
)
Se ha utilizado la etiqueta <em>fecha-de-la-fila-actual</em> para hacer referencia al valor del campo <em>Date</em> de la fila siendo considerada.
La función <a href="/es/dax/function/filter">FILTER</a>, siendo un iterador, va a crear un nuevo contexto de fila en el que evaluar la condición para cada fila de la tabla <em>data</em>:
data[Date] < fecha-de-la-fila-actual
Lógicamente, el siguiente código no funcionaría:
Number of Previous values =
COUNTROWS(
FILTER(
data,
data[Date] < data[Date])
)
)
...pues dentro del contexto de fila creado por <a href="/es/dax/function/filter">FILTER</a>, el valor de <em>data[Date]</em> es el valor del campo <em>Date</em> de la fila que <a href="/es/dax/function/filter">FILTER</a> esté iterando. Lo que querríamos es que el valor de <em>fecha-de-la-fila-actual</em> fuese el definido en el contexto de fila "anterior", el creado por la columna calculada previo a la ejecución de la función <a href="/es/dax/function/filter">FILTER</a>.
Para ello tenemos dos soluciones:
La primera -la única existente hasta que se introdujeron las variables en DAX en 2015- es recurrir a la función <a href="/es/dax/function/earlier">EARLIER</a>. Esta función nos devuelve exactamente lo que queremos: el valor de un campo para un contexto de fila anterior (pudiendo indicarse cuántos contextos de fila hay que retroceder). Por ejemplo:
Number of Previous values =
COUNTROWS(
FILTER(
data,
data[Date] < EARLIER(data[Date], 1)
)
)
...devolvería el resultado que buscábamos:
<a class="colorbox insert-colorbox" data-colorbox-gallery="gallery-node" data-insert-class="" data-insert-type="image" href="/sites/default/files/2021-06/dax-0111.jpg"></a>
Vemos que, para la primera fila, la función devuelve un <em>Blank</em> pues no hay filas con fechas anteriores y la función <a href="/es/dax/function/countrows">COUNTROWS</a> devuelve este valor para tablas vacías. Podemos forzar que, en este caso, se devuelva un 0 usando la función <a href="/es/dax/function/coalesce">COALESCE</a>:
Number of Previous values =
COALESCE(
COUNTROWS(
FILTER(
data,
data[Date] < EARLIER(data[Date], 1)
)
),
0
)
<a class="colorbox insert-colorbox" data-colorbox-gallery="gallery-node" data-insert-class="" data-insert-type="image" href="/sites/default/files/2021-06/dax-0112.jpg"></a>
En este caso, como el contexto "anterior" es el único contexto previo, también podríamos usar la función <a href="/es/dax/function/earliest">EARLIEST</a> que nos devuelve el valor del campo indicado en el último contexto de fila existente:
Number of Previous values =
COALESCE(
COUNTROWS(
FILTER(
data,
data[Date] < EARLIEST(data[Date])
)
),
0
)
El segundo método es, precisamente, haciendo uso de variables, lo que resulta mucho más sencillo y fácilmente interpretable. Concretamente:
Number of Previous values =
VAR __currentDate = data[Date]
RETURN
COUNTROWS(
FILTER(
data,
data[Date] < __currentDate
)
)
En primer lugar creamos una variable (<em>__currentDate</em>) con la palabra reservada <a href="/es/dax/function/var">VAR</a>. Esta variable se va a crear en el contexto de evaluación existente que, en ese punto del código, es el contexto de fila creado por la columna calculada. Es decir, en este punto, el campo <em>data[Date]</em> toma el valor del campo <em>Date</em> en la fila que se esté evaluando.
Una vez registrado el valor de la fecha se ejecuta el filtrado de la tabla <em>data</em>. Tal y como se ha comentado, la función <a href="/es/dax/function/filter">FILTER</a> crea un nuevo contexto de fila en el que se recorre la tabla en cuestión comparando cada valor del campo <em>Date</em> -evaluado en el contexto de fila de la función <a href="/es/dax/function/filter">FILTER</a>- con el valor registrado en la variable <em>__currentDate</em> (valor que se registró en el contexto de fila de la columna calculada):
<a class="colorbox insert-colorbox" data-colorbox-gallery="gallery-node" data-insert-class="" data-insert-type="image" href="/sites/default/files/2021-06/dax-0113.jpg"></a>
Comprobamos que el resultado es el mismo que obtuvimos con la función <a href="/es/dax/function/earlier">EARLIER</a> pero más fácil de interpretar.
Una vez más, podríamos usar la función <a href="/es/dax/function/coalesce">COALESCE</a> para forzar ceros allí donde <a href="/es/dax/function/countrows">COUNTROWS</a> devuelva <em>Blanks</em>:
Number of Previous values =
VAR __currentDate = data[Date]
RETURN
COALESCE(
COUNTROWS(
FILTER(
data,
data[Date] < __currentDate
)
),
0
)
', 'es') (Line: 118)
Drupal\filter\Element\ProcessedText::preRenderText(Array)
call_user_func_array(Array, Array) (Line: 101)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88)
__TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 46)
__TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 43)
__TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110)
__TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, ) (Line: 242)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
- Deprecated function: Creation of dynamic property Drupal\mysql\Driver\Database\mysql\Select::$alterTags is deprecated in Drupal\Core\Database\Query\Select->addTag() (line 149 of core/lib/Drupal/Core/Database/Query/Select.php).
Drupal\Core\Database\Query\Select->addTag('entity_query') (Line: 147)
Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80)
Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640)
Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63)
Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', 'insert-max_800_px-26f2094f-6fc5-4d8f-9cc2-da5576c21073') (Line: 95)
Drupal\editor\Plugin\Filter\EditorFileReference->process('En este escenario partimos de la siguiente tabla de datos:
<a class="colorbox insert-colorbox" data-colorbox-gallery="gallery-node" data-insert-class="" data-insert-type="image" href="/sites/default/files/2021-06/dax-0110.jpg"></a>
Obsérvese que en la tabla las fechas se muestran ordenadas (de más antiguas a más modernas) para hacer más sencilla su interpretación, pero tengamos en mente que podría no ser así.
El objetivo es crear una columna calculada que nos indique, para cada fila, cuántas filas de la misma tabla contienen fechas anteriores a la de la fila siendo considerada (teniendo en cuenta, como se ha comentado, que las filas podrían estar no ordenadas según la fecha).
Como queremos añadir una columna calculada, se va a crear por defecto un contexto de fila para cada una de las filas evaluadas. Es decir, para la primera fila (la correspondiente al campo <em>Id</em> 1) se creará un contexto de fila en el que podremos acceder a los valores de sus campos, <em>Id</em> y <em>Date</em>. A partir del valor del campo <em>Date</em> querríamos filtrar la tabla de forma que solo se considerasen las filas con fechas anteriores y contar el número de filas resultantes.
En pseudo código sería algo así:
Number of Previous values =
COUNTROWS(
FILTER(
data,
data[Date] < fecha-de-la-fila-actual
)
)
Se ha utilizado la etiqueta <em>fecha-de-la-fila-actual</em> para hacer referencia al valor del campo <em>Date</em> de la fila siendo considerada.
La función <a href="/es/dax/function/filter">FILTER</a>, siendo un iterador, va a crear un nuevo contexto de fila en el que evaluar la condición para cada fila de la tabla <em>data</em>:
data[Date] < fecha-de-la-fila-actual
Lógicamente, el siguiente código no funcionaría:
Number of Previous values =
COUNTROWS(
FILTER(
data,
data[Date] < data[Date])
)
)
...pues dentro del contexto de fila creado por <a href="/es/dax/function/filter">FILTER</a>, el valor de <em>data[Date]</em> es el valor del campo <em>Date</em> de la fila que <a href="/es/dax/function/filter">FILTER</a> esté iterando. Lo que querríamos es que el valor de <em>fecha-de-la-fila-actual</em> fuese el definido en el contexto de fila "anterior", el creado por la columna calculada previo a la ejecución de la función <a href="/es/dax/function/filter">FILTER</a>.
Para ello tenemos dos soluciones:
La primera -la única existente hasta que se introdujeron las variables en DAX en 2015- es recurrir a la función <a href="/es/dax/function/earlier">EARLIER</a>. Esta función nos devuelve exactamente lo que queremos: el valor de un campo para un contexto de fila anterior (pudiendo indicarse cuántos contextos de fila hay que retroceder). Por ejemplo:
Number of Previous values =
COUNTROWS(
FILTER(
data,
data[Date] < EARLIER(data[Date], 1)
)
)
...devolvería el resultado que buscábamos:
<a class="colorbox insert-colorbox" data-colorbox-gallery="gallery-node" data-insert-class="" data-insert-type="image" href="/sites/default/files/2021-06/dax-0111.jpg"></a>
Vemos que, para la primera fila, la función devuelve un <em>Blank</em> pues no hay filas con fechas anteriores y la función <a href="/es/dax/function/countrows">COUNTROWS</a> devuelve este valor para tablas vacías. Podemos forzar que, en este caso, se devuelva un 0 usando la función <a href="/es/dax/function/coalesce">COALESCE</a>:
Number of Previous values =
COALESCE(
COUNTROWS(
FILTER(
data,
data[Date] < EARLIER(data[Date], 1)
)
),
0
)
<a class="colorbox insert-colorbox" data-colorbox-gallery="gallery-node" data-insert-class="" data-insert-type="image" href="/sites/default/files/2021-06/dax-0112.jpg"></a>
En este caso, como el contexto "anterior" es el único contexto previo, también podríamos usar la función <a href="/es/dax/function/earliest">EARLIEST</a> que nos devuelve el valor del campo indicado en el último contexto de fila existente:
Number of Previous values =
COALESCE(
COUNTROWS(
FILTER(
data,
data[Date] < EARLIEST(data[Date])
)
),
0
)
El segundo método es, precisamente, haciendo uso de variables, lo que resulta mucho más sencillo y fácilmente interpretable. Concretamente:
Number of Previous values =
VAR __currentDate = data[Date]
RETURN
COUNTROWS(
FILTER(
data,
data[Date] < __currentDate
)
)
En primer lugar creamos una variable (<em>__currentDate</em>) con la palabra reservada <a href="/es/dax/function/var">VAR</a>. Esta variable se va a crear en el contexto de evaluación existente que, en ese punto del código, es el contexto de fila creado por la columna calculada. Es decir, en este punto, el campo <em>data[Date]</em> toma el valor del campo <em>Date</em> en la fila que se esté evaluando.
Una vez registrado el valor de la fecha se ejecuta el filtrado de la tabla <em>data</em>. Tal y como se ha comentado, la función <a href="/es/dax/function/filter">FILTER</a> crea un nuevo contexto de fila en el que se recorre la tabla en cuestión comparando cada valor del campo <em>Date</em> -evaluado en el contexto de fila de la función <a href="/es/dax/function/filter">FILTER</a>- con el valor registrado en la variable <em>__currentDate</em> (valor que se registró en el contexto de fila de la columna calculada):
<a class="colorbox insert-colorbox" data-colorbox-gallery="gallery-node" data-insert-class="" data-insert-type="image" href="/sites/default/files/2021-06/dax-0113.jpg"></a>
Comprobamos que el resultado es el mismo que obtuvimos con la función <a href="/es/dax/function/earlier">EARLIER</a> pero más fácil de interpretar.
Una vez más, podríamos usar la función <a href="/es/dax/function/coalesce">COALESCE</a> para forzar ceros allí donde <a href="/es/dax/function/countrows">COUNTROWS</a> devuelva <em>Blanks</em>:
Number of Previous values =
VAR __currentDate = data[Date]
RETURN
COALESCE(
COUNTROWS(
FILTER(
data,
data[Date] < __currentDate
)
),
0
)
', 'es') (Line: 118)
Drupal\filter\Element\ProcessedText::preRenderText(Array)
call_user_func_array(Array, Array) (Line: 101)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88)
__TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 46)
__TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 43)
__TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110)
__TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, ) (Line: 242)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
- Deprecated function: Creation of dynamic property Drupal\mysql\Driver\Database\mysql\Select::$alterMetaData is deprecated in Drupal\Core\Database\Query\Select->addMetaData() (line 178 of core/lib/Drupal/Core/Database/Query/Select.php).
Drupal\Core\Database\Query\Select->addMetaData('entity_type', 'file') (Line: 115)
Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80)
Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640)
Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63)
Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', 'insert-max_800_px-26f2094f-6fc5-4d8f-9cc2-da5576c21073') (Line: 124)
Drupal\editor\Plugin\Filter\EditorFileReference->process('En este escenario partimos de la siguiente tabla de datos:
<a class="colorbox insert-colorbox" data-colorbox-gallery="gallery-node" data-insert-class="" data-insert-type="image" href="/sites/default/files/2021-06/dax-0110.jpg"></a>
Obsérvese que en la tabla las fechas se muestran ordenadas (de más antiguas a más modernas) para hacer más sencilla su interpretación, pero tengamos en mente que podría no ser así.
El objetivo es crear una columna calculada que nos indique, para cada fila, cuántas filas de la misma tabla contienen fechas anteriores a la de la fila siendo considerada (teniendo en cuenta, como se ha comentado, que las filas podrían estar no ordenadas según la fecha).
Como queremos añadir una columna calculada, se va a crear por defecto un contexto de fila para cada una de las filas evaluadas. Es decir, para la primera fila (la correspondiente al campo <em>Id</em> 1) se creará un contexto de fila en el que podremos acceder a los valores de sus campos, <em>Id</em> y <em>Date</em>. A partir del valor del campo <em>Date</em> querríamos filtrar la tabla de forma que solo se considerasen las filas con fechas anteriores y contar el número de filas resultantes.
En pseudo código sería algo así:
Number of Previous values =
COUNTROWS(
FILTER(
data,
data[Date] < fecha-de-la-fila-actual
)
)
Se ha utilizado la etiqueta <em>fecha-de-la-fila-actual</em> para hacer referencia al valor del campo <em>Date</em> de la fila siendo considerada.
La función <a href="/es/dax/function/filter">FILTER</a>, siendo un iterador, va a crear un nuevo contexto de fila en el que evaluar la condición para cada fila de la tabla <em>data</em>:
data[Date] < fecha-de-la-fila-actual
Lógicamente, el siguiente código no funcionaría:
Number of Previous values =
COUNTROWS(
FILTER(
data,
data[Date] < data[Date])
)
)
...pues dentro del contexto de fila creado por <a href="/es/dax/function/filter">FILTER</a>, el valor de <em>data[Date]</em> es el valor del campo <em>Date</em> de la fila que <a href="/es/dax/function/filter">FILTER</a> esté iterando. Lo que querríamos es que el valor de <em>fecha-de-la-fila-actual</em> fuese el definido en el contexto de fila "anterior", el creado por la columna calculada previo a la ejecución de la función <a href="/es/dax/function/filter">FILTER</a>.
Para ello tenemos dos soluciones:
La primera -la única existente hasta que se introdujeron las variables en DAX en 2015- es recurrir a la función <a href="/es/dax/function/earlier">EARLIER</a>. Esta función nos devuelve exactamente lo que queremos: el valor de un campo para un contexto de fila anterior (pudiendo indicarse cuántos contextos de fila hay que retroceder). Por ejemplo:
Number of Previous values =
COUNTROWS(
FILTER(
data,
data[Date] < EARLIER(data[Date], 1)
)
)
...devolvería el resultado que buscábamos:
<a class="colorbox insert-colorbox" data-colorbox-gallery="gallery-node" data-insert-class="" data-insert-type="image" href="/sites/default/files/2021-06/dax-0111.jpg"></a>
Vemos que, para la primera fila, la función devuelve un <em>Blank</em> pues no hay filas con fechas anteriores y la función <a href="/es/dax/function/countrows">COUNTROWS</a> devuelve este valor para tablas vacías. Podemos forzar que, en este caso, se devuelva un 0 usando la función <a href="/es/dax/function/coalesce">COALESCE</a>:
Number of Previous values =
COALESCE(
COUNTROWS(
FILTER(
data,
data[Date] < EARLIER(data[Date], 1)
)
),
0
)
<a class="colorbox insert-colorbox" data-colorbox-gallery="gallery-node" data-insert-class="" data-insert-type="image" href="/sites/default/files/2021-06/dax-0112.jpg"></a>
En este caso, como el contexto "anterior" es el único contexto previo, también podríamos usar la función <a href="/es/dax/function/earliest">EARLIEST</a> que nos devuelve el valor del campo indicado en el último contexto de fila existente:
Number of Previous values =
COALESCE(
COUNTROWS(
FILTER(
data,
data[Date] < EARLIEST(data[Date])
)
),
0
)
El segundo método es, precisamente, haciendo uso de variables, lo que resulta mucho más sencillo y fácilmente interpretable. Concretamente:
Number of Previous values =
VAR __currentDate = data[Date]
RETURN
COUNTROWS(
FILTER(
data,
data[Date] < __currentDate
)
)
En primer lugar creamos una variable (<em>__currentDate</em>) con la palabra reservada <a href="/es/dax/function/var">VAR</a>. Esta variable se va a crear en el contexto de evaluación existente que, en ese punto del código, es el contexto de fila creado por la columna calculada. Es decir, en este punto, el campo <em>data[Date]</em> toma el valor del campo <em>Date</em> en la fila que se esté evaluando.
Una vez registrado el valor de la fecha se ejecuta el filtrado de la tabla <em>data</em>. Tal y como se ha comentado, la función <a href="/es/dax/function/filter">FILTER</a> crea un nuevo contexto de fila en el que se recorre la tabla en cuestión comparando cada valor del campo <em>Date</em> -evaluado en el contexto de fila de la función <a href="/es/dax/function/filter">FILTER</a>- con el valor registrado en la variable <em>__currentDate</em> (valor que se registró en el contexto de fila de la columna calculada):
<a class="colorbox insert-colorbox" data-colorbox-gallery="gallery-node" data-insert-class="" data-insert-type="image" href="/sites/default/files/2021-06/dax-0113.jpg"></a>
Comprobamos que el resultado es el mismo que obtuvimos con la función <a href="/es/dax/function/earlier">EARLIER</a> pero más fácil de interpretar.
Una vez más, podríamos usar la función <a href="/es/dax/function/coalesce">COALESCE</a> para forzar ceros allí donde <a href="/es/dax/function/countrows">COUNTROWS</a> devuelva <em>Blanks</em>:
Number of Previous values =
VAR __currentDate = data[Date]
RETURN
COALESCE(
COUNTROWS(
FILTER(
data,
data[Date] < __currentDate
)
),
0
)
', 'es') (Line: 118)
Drupal\filter\Element\ProcessedText::preRenderText(Array)
call_user_func_array(Array, Array) (Line: 101)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88)
__TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 46)
__TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 43)
__TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110)
__TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, ) (Line: 242)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
- Deprecated function: Creation of dynamic property Drupal\mysql\Driver\Database\mysql\Select::$alterTags is deprecated in Drupal\Core\Database\Query\Select->addTag() (line 149 of core/lib/Drupal/Core/Database/Query/Select.php).
Drupal\Core\Database\Query\Select->addTag('entity_query') (Line: 147)
Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80)
Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640)
Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63)
Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', 'insert-max_800_px-26f2094f-6fc5-4d8f-9cc2-da5576c21073') (Line: 124)
Drupal\editor\Plugin\Filter\EditorFileReference->process('En este escenario partimos de la siguiente tabla de datos:
<a class="colorbox insert-colorbox" data-colorbox-gallery="gallery-node" data-insert-class="" data-insert-type="image" href="/sites/default/files/2021-06/dax-0110.jpg"></a>
Obsérvese que en la tabla las fechas se muestran ordenadas (de más antiguas a más modernas) para hacer más sencilla su interpretación, pero tengamos en mente que podría no ser así.
El objetivo es crear una columna calculada que nos indique, para cada fila, cuántas filas de la misma tabla contienen fechas anteriores a la de la fila siendo considerada (teniendo en cuenta, como se ha comentado, que las filas podrían estar no ordenadas según la fecha).
Como queremos añadir una columna calculada, se va a crear por defecto un contexto de fila para cada una de las filas evaluadas. Es decir, para la primera fila (la correspondiente al campo <em>Id</em> 1) se creará un contexto de fila en el que podremos acceder a los valores de sus campos, <em>Id</em> y <em>Date</em>. A partir del valor del campo <em>Date</em> querríamos filtrar la tabla de forma que solo se considerasen las filas con fechas anteriores y contar el número de filas resultantes.
En pseudo código sería algo así:
Number of Previous values =
COUNTROWS(
FILTER(
data,
data[Date] < fecha-de-la-fila-actual
)
)
Se ha utilizado la etiqueta <em>fecha-de-la-fila-actual</em> para hacer referencia al valor del campo <em>Date</em> de la fila siendo considerada.
La función <a href="/es/dax/function/filter">FILTER</a>, siendo un iterador, va a crear un nuevo contexto de fila en el que evaluar la condición para cada fila de la tabla <em>data</em>:
data[Date] < fecha-de-la-fila-actual
Lógicamente, el siguiente código no funcionaría:
Number of Previous values =
COUNTROWS(
FILTER(
data,
data[Date] < data[Date])
)
)
...pues dentro del contexto de fila creado por <a href="/es/dax/function/filter">FILTER</a>, el valor de <em>data[Date]</em> es el valor del campo <em>Date</em> de la fila que <a href="/es/dax/function/filter">FILTER</a> esté iterando. Lo que querríamos es que el valor de <em>fecha-de-la-fila-actual</em> fuese el definido en el contexto de fila "anterior", el creado por la columna calculada previo a la ejecución de la función <a href="/es/dax/function/filter">FILTER</a>.
Para ello tenemos dos soluciones:
La primera -la única existente hasta que se introdujeron las variables en DAX en 2015- es recurrir a la función <a href="/es/dax/function/earlier">EARLIER</a>. Esta función nos devuelve exactamente lo que queremos: el valor de un campo para un contexto de fila anterior (pudiendo indicarse cuántos contextos de fila hay que retroceder). Por ejemplo:
Number of Previous values =
COUNTROWS(
FILTER(
data,
data[Date] < EARLIER(data[Date], 1)
)
)
...devolvería el resultado que buscábamos:
<a class="colorbox insert-colorbox" data-colorbox-gallery="gallery-node" data-insert-class="" data-insert-type="image" href="/sites/default/files/2021-06/dax-0111.jpg"></a>
Vemos que, para la primera fila, la función devuelve un <em>Blank</em> pues no hay filas con fechas anteriores y la función <a href="/es/dax/function/countrows">COUNTROWS</a> devuelve este valor para tablas vacías. Podemos forzar que, en este caso, se devuelva un 0 usando la función <a href="/es/dax/function/coalesce">COALESCE</a>:
Number of Previous values =
COALESCE(
COUNTROWS(
FILTER(
data,
data[Date] < EARLIER(data[Date], 1)
)
),
0
)
<a class="colorbox insert-colorbox" data-colorbox-gallery="gallery-node" data-insert-class="" data-insert-type="image" href="/sites/default/files/2021-06/dax-0112.jpg"></a>
En este caso, como el contexto "anterior" es el único contexto previo, también podríamos usar la función <a href="/es/dax/function/earliest">EARLIEST</a> que nos devuelve el valor del campo indicado en el último contexto de fila existente:
Number of Previous values =
COALESCE(
COUNTROWS(
FILTER(
data,
data[Date] < EARLIEST(data[Date])
)
),
0
)
El segundo método es, precisamente, haciendo uso de variables, lo que resulta mucho más sencillo y fácilmente interpretable. Concretamente:
Number of Previous values =
VAR __currentDate = data[Date]
RETURN
COUNTROWS(
FILTER(
data,
data[Date] < __currentDate
)
)
En primer lugar creamos una variable (<em>__currentDate</em>) con la palabra reservada <a href="/es/dax/function/var">VAR</a>. Esta variable se va a crear en el contexto de evaluación existente que, en ese punto del código, es el contexto de fila creado por la columna calculada. Es decir, en este punto, el campo <em>data[Date]</em> toma el valor del campo <em>Date</em> en la fila que se esté evaluando.
Una vez registrado el valor de la fecha se ejecuta el filtrado de la tabla <em>data</em>. Tal y como se ha comentado, la función <a href="/es/dax/function/filter">FILTER</a> crea un nuevo contexto de fila en el que se recorre la tabla en cuestión comparando cada valor del campo <em>Date</em> -evaluado en el contexto de fila de la función <a href="/es/dax/function/filter">FILTER</a>- con el valor registrado en la variable <em>__currentDate</em> (valor que se registró en el contexto de fila de la columna calculada):
<a class="colorbox insert-colorbox" data-colorbox-gallery="gallery-node" data-insert-class="" data-insert-type="image" href="/sites/default/files/2021-06/dax-0113.jpg"></a>
Comprobamos que el resultado es el mismo que obtuvimos con la función <a href="/es/dax/function/earlier">EARLIER</a> pero más fácil de interpretar.
Una vez más, podríamos usar la función <a href="/es/dax/function/coalesce">COALESCE</a> para forzar ceros allí donde <a href="/es/dax/function/countrows">COUNTROWS</a> devuelva <em>Blanks</em>:
Number of Previous values =
VAR __currentDate = data[Date]
RETURN
COALESCE(
COUNTROWS(
FILTER(
data,
data[Date] < __currentDate
)
),
0
)
', 'es') (Line: 118)
Drupal\filter\Element\ProcessedText::preRenderText(Array)
call_user_func_array(Array, Array) (Line: 101)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88)
__TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 46)
__TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 43)
__TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110)
__TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, ) (Line: 242)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
- Deprecated function: Creation of dynamic property Drupal\mysql\Driver\Database\mysql\Select::$alterMetaData is deprecated in Drupal\Core\Database\Query\Select->addMetaData() (line 178 of core/lib/Drupal/Core/Database/Query/Select.php).
Drupal\Core\Database\Query\Select->addMetaData('entity_type', 'file') (Line: 115)
Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80)
Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640)
Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63)
Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', 'insert-max_800_px-5b76a210-02d1-4484-a8b9-c3a70422d70c') (Line: 95)
Drupal\editor\Plugin\Filter\EditorFileReference->process('En este escenario partimos de la siguiente tabla de datos:
<a class="colorbox insert-colorbox" data-colorbox-gallery="gallery-node" data-insert-class="" data-insert-type="image" href="/sites/default/files/2021-06/dax-0110.jpg"></a>
Obsérvese que en la tabla las fechas se muestran ordenadas (de más antiguas a más modernas) para hacer más sencilla su interpretación, pero tengamos en mente que podría no ser así.
El objetivo es crear una columna calculada que nos indique, para cada fila, cuántas filas de la misma tabla contienen fechas anteriores a la de la fila siendo considerada (teniendo en cuenta, como se ha comentado, que las filas podrían estar no ordenadas según la fecha).
Como queremos añadir una columna calculada, se va a crear por defecto un contexto de fila para cada una de las filas evaluadas. Es decir, para la primera fila (la correspondiente al campo <em>Id</em> 1) se creará un contexto de fila en el que podremos acceder a los valores de sus campos, <em>Id</em> y <em>Date</em>. A partir del valor del campo <em>Date</em> querríamos filtrar la tabla de forma que solo se considerasen las filas con fechas anteriores y contar el número de filas resultantes.
En pseudo código sería algo así:
Number of Previous values =
COUNTROWS(
FILTER(
data,
data[Date] < fecha-de-la-fila-actual
)
)
Se ha utilizado la etiqueta <em>fecha-de-la-fila-actual</em> para hacer referencia al valor del campo <em>Date</em> de la fila siendo considerada.
La función <a href="/es/dax/function/filter">FILTER</a>, siendo un iterador, va a crear un nuevo contexto de fila en el que evaluar la condición para cada fila de la tabla <em>data</em>:
data[Date] < fecha-de-la-fila-actual
Lógicamente, el siguiente código no funcionaría:
Number of Previous values =
COUNTROWS(
FILTER(
data,
data[Date] < data[Date])
)
)
...pues dentro del contexto de fila creado por <a href="/es/dax/function/filter">FILTER</a>, el valor de <em>data[Date]</em> es el valor del campo <em>Date</em> de la fila que <a href="/es/dax/function/filter">FILTER</a> esté iterando. Lo que querríamos es que el valor de <em>fecha-de-la-fila-actual</em> fuese el definido en el contexto de fila "anterior", el creado por la columna calculada previo a la ejecución de la función <a href="/es/dax/function/filter">FILTER</a>.
Para ello tenemos dos soluciones:
La primera -la única existente hasta que se introdujeron las variables en DAX en 2015- es recurrir a la función <a href="/es/dax/function/earlier">EARLIER</a>. Esta función nos devuelve exactamente lo que queremos: el valor de un campo para un contexto de fila anterior (pudiendo indicarse cuántos contextos de fila hay que retroceder). Por ejemplo:
Number of Previous values =
COUNTROWS(
FILTER(
data,
data[Date] < EARLIER(data[Date], 1)
)
)
...devolvería el resultado que buscábamos:
<a class="colorbox insert-colorbox" data-colorbox-gallery="gallery-node" data-insert-class="" data-insert-type="image" href="/sites/default/files/2021-06/dax-0111.jpg"></a>
Vemos que, para la primera fila, la función devuelve un <em>Blank</em> pues no hay filas con fechas anteriores y la función <a href="/es/dax/function/countrows">COUNTROWS</a> devuelve este valor para tablas vacías. Podemos forzar que, en este caso, se devuelva un 0 usando la función <a href="/es/dax/function/coalesce">COALESCE</a>:
Number of Previous values =
COALESCE(
COUNTROWS(
FILTER(
data,
data[Date] < EARLIER(data[Date], 1)
)
),
0
)
<a class="colorbox insert-colorbox" data-colorbox-gallery="gallery-node" data-insert-class="" data-insert-type="image" href="/sites/default/files/2021-06/dax-0112.jpg"></a>
En este caso, como el contexto "anterior" es el único contexto previo, también podríamos usar la función <a href="/es/dax/function/earliest">EARLIEST</a> que nos devuelve el valor del campo indicado en el último contexto de fila existente:
Number of Previous values =
COALESCE(
COUNTROWS(
FILTER(
data,
data[Date] < EARLIEST(data[Date])
)
),
0
)
El segundo método es, precisamente, haciendo uso de variables, lo que resulta mucho más sencillo y fácilmente interpretable. Concretamente:
Number of Previous values =
VAR __currentDate = data[Date]
RETURN
COUNTROWS(
FILTER(
data,
data[Date] < __currentDate
)
)
En primer lugar creamos una variable (<em>__currentDate</em>) con la palabra reservada <a href="/es/dax/function/var">VAR</a>. Esta variable se va a crear en el contexto de evaluación existente que, en ese punto del código, es el contexto de fila creado por la columna calculada. Es decir, en este punto, el campo <em>data[Date]</em> toma el valor del campo <em>Date</em> en la fila que se esté evaluando.
Una vez registrado el valor de la fecha se ejecuta el filtrado de la tabla <em>data</em>. Tal y como se ha comentado, la función <a href="/es/dax/function/filter">FILTER</a> crea un nuevo contexto de fila en el que se recorre la tabla en cuestión comparando cada valor del campo <em>Date</em> -evaluado en el contexto de fila de la función <a href="/es/dax/function/filter">FILTER</a>- con el valor registrado en la variable <em>__currentDate</em> (valor que se registró en el contexto de fila de la columna calculada):
<a class="colorbox insert-colorbox" data-colorbox-gallery="gallery-node" data-insert-class="" data-insert-type="image" href="/sites/default/files/2021-06/dax-0113.jpg"></a>
Comprobamos que el resultado es el mismo que obtuvimos con la función <a href="/es/dax/function/earlier">EARLIER</a> pero más fácil de interpretar.
Una vez más, podríamos usar la función <a href="/es/dax/function/coalesce">COALESCE</a> para forzar ceros allí donde <a href="/es/dax/function/countrows">COUNTROWS</a> devuelva <em>Blanks</em>:
Number of Previous values =
VAR __currentDate = data[Date]
RETURN
COALESCE(
COUNTROWS(
FILTER(
data,
data[Date] < __currentDate
)
),
0
)
', 'es') (Line: 118)
Drupal\filter\Element\ProcessedText::preRenderText(Array)
call_user_func_array(Array, Array) (Line: 101)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88)
__TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 46)
__TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 43)
__TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110)
__TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, ) (Line: 242)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
- Deprecated function: Creation of dynamic property Drupal\mysql\Driver\Database\mysql\Select::$alterTags is deprecated in Drupal\Core\Database\Query\Select->addTag() (line 149 of core/lib/Drupal/Core/Database/Query/Select.php).
Drupal\Core\Database\Query\Select->addTag('entity_query') (Line: 147)
Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80)
Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640)
Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63)
Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', 'insert-max_800_px-5b76a210-02d1-4484-a8b9-c3a70422d70c') (Line: 95)
Drupal\editor\Plugin\Filter\EditorFileReference->process('En este escenario partimos de la siguiente tabla de datos:
<a class="colorbox insert-colorbox" data-colorbox-gallery="gallery-node" data-insert-class="" data-insert-type="image" href="/sites/default/files/2021-06/dax-0110.jpg"></a>
Obsérvese que en la tabla las fechas se muestran ordenadas (de más antiguas a más modernas) para hacer más sencilla su interpretación, pero tengamos en mente que podría no ser así.
El objetivo es crear una columna calculada que nos indique, para cada fila, cuántas filas de la misma tabla contienen fechas anteriores a la de la fila siendo considerada (teniendo en cuenta, como se ha comentado, que las filas podrían estar no ordenadas según la fecha).
Como queremos añadir una columna calculada, se va a crear por defecto un contexto de fila para cada una de las filas evaluadas. Es decir, para la primera fila (la correspondiente al campo <em>Id</em> 1) se creará un contexto de fila en el que podremos acceder a los valores de sus campos, <em>Id</em> y <em>Date</em>. A partir del valor del campo <em>Date</em> querríamos filtrar la tabla de forma que solo se considerasen las filas con fechas anteriores y contar el número de filas resultantes.
En pseudo código sería algo así:
Number of Previous values =
COUNTROWS(
FILTER(
data,
data[Date] < fecha-de-la-fila-actual
)
)
Se ha utilizado la etiqueta <em>fecha-de-la-fila-actual</em> para hacer referencia al valor del campo <em>Date</em> de la fila siendo considerada.
La función <a href="/es/dax/function/filter">FILTER</a>, siendo un iterador, va a crear un nuevo contexto de fila en el que evaluar la condición para cada fila de la tabla <em>data</em>:
data[Date] < fecha-de-la-fila-actual
Lógicamente, el siguiente código no funcionaría:
Number of Previous values =
COUNTROWS(
FILTER(
data,
data[Date] < data[Date])
)
)
...pues dentro del contexto de fila creado por <a href="/es/dax/function/filter">FILTER</a>, el valor de <em>data[Date]</em> es el valor del campo <em>Date</em> de la fila que <a href="/es/dax/function/filter">FILTER</a> esté iterando. Lo que querríamos es que el valor de <em>fecha-de-la-fila-actual</em> fuese el definido en el contexto de fila "anterior", el creado por la columna calculada previo a la ejecución de la función <a href="/es/dax/function/filter">FILTER</a>.
Para ello tenemos dos soluciones:
La primera -la única existente hasta que se introdujeron las variables en DAX en 2015- es recurrir a la función <a href="/es/dax/function/earlier">EARLIER</a>. Esta función nos devuelve exactamente lo que queremos: el valor de un campo para un contexto de fila anterior (pudiendo indicarse cuántos contextos de fila hay que retroceder). Por ejemplo:
Number of Previous values =
COUNTROWS(
FILTER(
data,
data[Date] < EARLIER(data[Date], 1)
)
)
...devolvería el resultado que buscábamos:
<a class="colorbox insert-colorbox" data-colorbox-gallery="gallery-node" data-insert-class="" data-insert-type="image" href="/sites/default/files/2021-06/dax-0111.jpg"></a>
Vemos que, para la primera fila, la función devuelve un <em>Blank</em> pues no hay filas con fechas anteriores y la función <a href="/es/dax/function/countrows">COUNTROWS</a> devuelve este valor para tablas vacías. Podemos forzar que, en este caso, se devuelva un 0 usando la función <a href="/es/dax/function/coalesce">COALESCE</a>:
Number of Previous values =
COALESCE(
COUNTROWS(
FILTER(
data,
data[Date] < EARLIER(data[Date], 1)
)
),
0
)
<a class="colorbox insert-colorbox" data-colorbox-gallery="gallery-node" data-insert-class="" data-insert-type="image" href="/sites/default/files/2021-06/dax-0112.jpg"></a>
En este caso, como el contexto "anterior" es el único contexto previo, también podríamos usar la función <a href="/es/dax/function/earliest">EARLIEST</a> que nos devuelve el valor del campo indicado en el último contexto de fila existente:
Number of Previous values =
COALESCE(
COUNTROWS(
FILTER(
data,
data[Date] < EARLIEST(data[Date])
)
),
0
)
El segundo método es, precisamente, haciendo uso de variables, lo que resulta mucho más sencillo y fácilmente interpretable. Concretamente:
Number of Previous values =
VAR __currentDate = data[Date]
RETURN
COUNTROWS(
FILTER(
data,
data[Date] < __currentDate
)
)
En primer lugar creamos una variable (<em>__currentDate</em>) con la palabra reservada <a href="/es/dax/function/var">VAR</a>. Esta variable se va a crear en el contexto de evaluación existente que, en ese punto del código, es el contexto de fila creado por la columna calculada. Es decir, en este punto, el campo <em>data[Date]</em> toma el valor del campo <em>Date</em> en la fila que se esté evaluando.
Una vez registrado el valor de la fecha se ejecuta el filtrado de la tabla <em>data</em>. Tal y como se ha comentado, la función <a href="/es/dax/function/filter">FILTER</a> crea un nuevo contexto de fila en el que se recorre la tabla en cuestión comparando cada valor del campo <em>Date</em> -evaluado en el contexto de fila de la función <a href="/es/dax/function/filter">FILTER</a>- con el valor registrado en la variable <em>__currentDate</em> (valor que se registró en el contexto de fila de la columna calculada):
<a class="colorbox insert-colorbox" data-colorbox-gallery="gallery-node" data-insert-class="" data-insert-type="image" href="/sites/default/files/2021-06/dax-0113.jpg"></a>
Comprobamos que el resultado es el mismo que obtuvimos con la función <a href="/es/dax/function/earlier">EARLIER</a> pero más fácil de interpretar.
Una vez más, podríamos usar la función <a href="/es/dax/function/coalesce">COALESCE</a> para forzar ceros allí donde <a href="/es/dax/function/countrows">COUNTROWS</a> devuelva <em>Blanks</em>:
Number of Previous values =
VAR __currentDate = data[Date]
RETURN
COALESCE(
COUNTROWS(
FILTER(
data,
data[Date] < __currentDate
)
),
0
)
', 'es') (Line: 118)
Drupal\filter\Element\ProcessedText::preRenderText(Array)
call_user_func_array(Array, Array) (Line: 101)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88)
__TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 46)
__TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 43)
__TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110)
__TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, ) (Line: 242)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
- Deprecated function: Creation of dynamic property Drupal\mysql\Driver\Database\mysql\Select::$alterMetaData is deprecated in Drupal\Core\Database\Query\Select->addMetaData() (line 178 of core/lib/Drupal/Core/Database/Query/Select.php).
Drupal\Core\Database\Query\Select->addMetaData('entity_type', 'file') (Line: 115)
Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80)
Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640)
Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63)
Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', 'insert-max_800_px-5b76a210-02d1-4484-a8b9-c3a70422d70c') (Line: 124)
Drupal\editor\Plugin\Filter\EditorFileReference->process('En este escenario partimos de la siguiente tabla de datos:
<a class="colorbox insert-colorbox" data-colorbox-gallery="gallery-node" data-insert-class="" data-insert-type="image" href="/sites/default/files/2021-06/dax-0110.jpg"></a>
Obsérvese que en la tabla las fechas se muestran ordenadas (de más antiguas a más modernas) para hacer más sencilla su interpretación, pero tengamos en mente que podría no ser así.
El objetivo es crear una columna calculada que nos indique, para cada fila, cuántas filas de la misma tabla contienen fechas anteriores a la de la fila siendo considerada (teniendo en cuenta, como se ha comentado, que las filas podrían estar no ordenadas según la fecha).
Como queremos añadir una columna calculada, se va a crear por defecto un contexto de fila para cada una de las filas evaluadas. Es decir, para la primera fila (la correspondiente al campo <em>Id</em> 1) se creará un contexto de fila en el que podremos acceder a los valores de sus campos, <em>Id</em> y <em>Date</em>. A partir del valor del campo <em>Date</em> querríamos filtrar la tabla de forma que solo se considerasen las filas con fechas anteriores y contar el número de filas resultantes.
En pseudo código sería algo así:
Number of Previous values =
COUNTROWS(
FILTER(
data,
data[Date] < fecha-de-la-fila-actual
)
)
Se ha utilizado la etiqueta <em>fecha-de-la-fila-actual</em> para hacer referencia al valor del campo <em>Date</em> de la fila siendo considerada.
La función <a href="/es/dax/function/filter">FILTER</a>, siendo un iterador, va a crear un nuevo contexto de fila en el que evaluar la condición para cada fila de la tabla <em>data</em>:
data[Date] < fecha-de-la-fila-actual
Lógicamente, el siguiente código no funcionaría:
Number of Previous values =
COUNTROWS(
FILTER(
data,
data[Date] < data[Date])
)
)
...pues dentro del contexto de fila creado por <a href="/es/dax/function/filter">FILTER</a>, el valor de <em>data[Date]</em> es el valor del campo <em>Date</em> de la fila que <a href="/es/dax/function/filter">FILTER</a> esté iterando. Lo que querríamos es que el valor de <em>fecha-de-la-fila-actual</em> fuese el definido en el contexto de fila "anterior", el creado por la columna calculada previo a la ejecución de la función <a href="/es/dax/function/filter">FILTER</a>.
Para ello tenemos dos soluciones:
La primera -la única existente hasta que se introdujeron las variables en DAX en 2015- es recurrir a la función <a href="/es/dax/function/earlier">EARLIER</a>. Esta función nos devuelve exactamente lo que queremos: el valor de un campo para un contexto de fila anterior (pudiendo indicarse cuántos contextos de fila hay que retroceder). Por ejemplo:
Number of Previous values =
COUNTROWS(
FILTER(
data,
data[Date] < EARLIER(data[Date], 1)
)
)
...devolvería el resultado que buscábamos:
<a class="colorbox insert-colorbox" data-colorbox-gallery="gallery-node" data-insert-class="" data-insert-type="image" href="/sites/default/files/2021-06/dax-0111.jpg"></a>
Vemos que, para la primera fila, la función devuelve un <em>Blank</em> pues no hay filas con fechas anteriores y la función <a href="/es/dax/function/countrows">COUNTROWS</a> devuelve este valor para tablas vacías. Podemos forzar que, en este caso, se devuelva un 0 usando la función <a href="/es/dax/function/coalesce">COALESCE</a>:
Number of Previous values =
COALESCE(
COUNTROWS(
FILTER(
data,
data[Date] < EARLIER(data[Date], 1)
)
),
0
)
<a class="colorbox insert-colorbox" data-colorbox-gallery="gallery-node" data-insert-class="" data-insert-type="image" href="/sites/default/files/2021-06/dax-0112.jpg"></a>
En este caso, como el contexto "anterior" es el único contexto previo, también podríamos usar la función <a href="/es/dax/function/earliest">EARLIEST</a> que nos devuelve el valor del campo indicado en el último contexto de fila existente:
Number of Previous values =
COALESCE(
COUNTROWS(
FILTER(
data,
data[Date] < EARLIEST(data[Date])
)
),
0
)
El segundo método es, precisamente, haciendo uso de variables, lo que resulta mucho más sencillo y fácilmente interpretable. Concretamente:
Number of Previous values =
VAR __currentDate = data[Date]
RETURN
COUNTROWS(
FILTER(
data,
data[Date] < __currentDate
)
)
En primer lugar creamos una variable (<em>__currentDate</em>) con la palabra reservada <a href="/es/dax/function/var">VAR</a>. Esta variable se va a crear en el contexto de evaluación existente que, en ese punto del código, es el contexto de fila creado por la columna calculada. Es decir, en este punto, el campo <em>data[Date]</em> toma el valor del campo <em>Date</em> en la fila que se esté evaluando.
Una vez registrado el valor de la fecha se ejecuta el filtrado de la tabla <em>data</em>. Tal y como se ha comentado, la función <a href="/es/dax/function/filter">FILTER</a> crea un nuevo contexto de fila en el que se recorre la tabla en cuestión comparando cada valor del campo <em>Date</em> -evaluado en el contexto de fila de la función <a href="/es/dax/function/filter">FILTER</a>- con el valor registrado en la variable <em>__currentDate</em> (valor que se registró en el contexto de fila de la columna calculada):
<a class="colorbox insert-colorbox" data-colorbox-gallery="gallery-node" data-insert-class="" data-insert-type="image" href="/sites/default/files/2021-06/dax-0113.jpg"></a>
Comprobamos que el resultado es el mismo que obtuvimos con la función <a href="/es/dax/function/earlier">EARLIER</a> pero más fácil de interpretar.
Una vez más, podríamos usar la función <a href="/es/dax/function/coalesce">COALESCE</a> para forzar ceros allí donde <a href="/es/dax/function/countrows">COUNTROWS</a> devuelva <em>Blanks</em>:
Number of Previous values =
VAR __currentDate = data[Date]
RETURN
COALESCE(
COUNTROWS(
FILTER(
data,
data[Date] < __currentDate
)
),
0
)
', 'es') (Line: 118)
Drupal\filter\Element\ProcessedText::preRenderText(Array)
call_user_func_array(Array, Array) (Line: 101)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88)
__TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 46)
__TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 43)
__TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110)
__TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, ) (Line: 242)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
- Deprecated function: Creation of dynamic property Drupal\mysql\Driver\Database\mysql\Select::$alterTags is deprecated in Drupal\Core\Database\Query\Select->addTag() (line 149 of core/lib/Drupal/Core/Database/Query/Select.php).
Drupal\Core\Database\Query\Select->addTag('entity_query') (Line: 147)
Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80)
Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640)
Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63)
Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', 'insert-max_800_px-5b76a210-02d1-4484-a8b9-c3a70422d70c') (Line: 124)
Drupal\editor\Plugin\Filter\EditorFileReference->process('En este escenario partimos de la siguiente tabla de datos:
<a class="colorbox insert-colorbox" data-colorbox-gallery="gallery-node" data-insert-class="" data-insert-type="image" href="/sites/default/files/2021-06/dax-0110.jpg"></a>
Obsérvese que en la tabla las fechas se muestran ordenadas (de más antiguas a más modernas) para hacer más sencilla su interpretación, pero tengamos en mente que podría no ser así.
El objetivo es crear una columna calculada que nos indique, para cada fila, cuántas filas de la misma tabla contienen fechas anteriores a la de la fila siendo considerada (teniendo en cuenta, como se ha comentado, que las filas podrían estar no ordenadas según la fecha).
Como queremos añadir una columna calculada, se va a crear por defecto un contexto de fila para cada una de las filas evaluadas. Es decir, para la primera fila (la correspondiente al campo <em>Id</em> 1) se creará un contexto de fila en el que podremos acceder a los valores de sus campos, <em>Id</em> y <em>Date</em>. A partir del valor del campo <em>Date</em> querríamos filtrar la tabla de forma que solo se considerasen las filas con fechas anteriores y contar el número de filas resultantes.
En pseudo código sería algo así:
Number of Previous values =
COUNTROWS(
FILTER(
data,
data[Date] < fecha-de-la-fila-actual
)
)
Se ha utilizado la etiqueta <em>fecha-de-la-fila-actual</em> para hacer referencia al valor del campo <em>Date</em> de la fila siendo considerada.
La función <a href="/es/dax/function/filter">FILTER</a>, siendo un iterador, va a crear un nuevo contexto de fila en el que evaluar la condición para cada fila de la tabla <em>data</em>:
data[Date] < fecha-de-la-fila-actual
Lógicamente, el siguiente código no funcionaría:
Number of Previous values =
COUNTROWS(
FILTER(
data,
data[Date] < data[Date])
)
)
...pues dentro del contexto de fila creado por <a href="/es/dax/function/filter">FILTER</a>, el valor de <em>data[Date]</em> es el valor del campo <em>Date</em> de la fila que <a href="/es/dax/function/filter">FILTER</a> esté iterando. Lo que querríamos es que el valor de <em>fecha-de-la-fila-actual</em> fuese el definido en el contexto de fila "anterior", el creado por la columna calculada previo a la ejecución de la función <a href="/es/dax/function/filter">FILTER</a>.
Para ello tenemos dos soluciones:
La primera -la única existente hasta que se introdujeron las variables en DAX en 2015- es recurrir a la función <a href="/es/dax/function/earlier">EARLIER</a>. Esta función nos devuelve exactamente lo que queremos: el valor de un campo para un contexto de fila anterior (pudiendo indicarse cuántos contextos de fila hay que retroceder). Por ejemplo:
Number of Previous values =
COUNTROWS(
FILTER(
data,
data[Date] < EARLIER(data[Date], 1)
)
)
...devolvería el resultado que buscábamos:
<a class="colorbox insert-colorbox" data-colorbox-gallery="gallery-node" data-insert-class="" data-insert-type="image" href="/sites/default/files/2021-06/dax-0111.jpg"></a>
Vemos que, para la primera fila, la función devuelve un <em>Blank</em> pues no hay filas con fechas anteriores y la función <a href="/es/dax/function/countrows">COUNTROWS</a> devuelve este valor para tablas vacías. Podemos forzar que, en este caso, se devuelva un 0 usando la función <a href="/es/dax/function/coalesce">COALESCE</a>:
Number of Previous values =
COALESCE(
COUNTROWS(
FILTER(
data,
data[Date] < EARLIER(data[Date], 1)
)
),
0
)
<a class="colorbox insert-colorbox" data-colorbox-gallery="gallery-node" data-insert-class="" data-insert-type="image" href="/sites/default/files/2021-06/dax-0112.jpg"></a>
En este caso, como el contexto "anterior" es el único contexto previo, también podríamos usar la función <a href="/es/dax/function/earliest">EARLIEST</a> que nos devuelve el valor del campo indicado en el último contexto de fila existente:
Number of Previous values =
COALESCE(
COUNTROWS(
FILTER(
data,
data[Date] < EARLIEST(data[Date])
)
),
0
)
El segundo método es, precisamente, haciendo uso de variables, lo que resulta mucho más sencillo y fácilmente interpretable. Concretamente:
Number of Previous values =
VAR __currentDate = data[Date]
RETURN
COUNTROWS(
FILTER(
data,
data[Date] < __currentDate
)
)
En primer lugar creamos una variable (<em>__currentDate</em>) con la palabra reservada <a href="/es/dax/function/var">VAR</a>. Esta variable se va a crear en el contexto de evaluación existente que, en ese punto del código, es el contexto de fila creado por la columna calculada. Es decir, en este punto, el campo <em>data[Date]</em> toma el valor del campo <em>Date</em> en la fila que se esté evaluando.
Una vez registrado el valor de la fecha se ejecuta el filtrado de la tabla <em>data</em>. Tal y como se ha comentado, la función <a href="/es/dax/function/filter">FILTER</a> crea un nuevo contexto de fila en el que se recorre la tabla en cuestión comparando cada valor del campo <em>Date</em> -evaluado en el contexto de fila de la función <a href="/es/dax/function/filter">FILTER</a>- con el valor registrado en la variable <em>__currentDate</em> (valor que se registró en el contexto de fila de la columna calculada):
<a class="colorbox insert-colorbox" data-colorbox-gallery="gallery-node" data-insert-class="" data-insert-type="image" href="/sites/default/files/2021-06/dax-0113.jpg"></a>
Comprobamos que el resultado es el mismo que obtuvimos con la función <a href="/es/dax/function/earlier">EARLIER</a> pero más fácil de interpretar.
Una vez más, podríamos usar la función <a href="/es/dax/function/coalesce">COALESCE</a> para forzar ceros allí donde <a href="/es/dax/function/countrows">COUNTROWS</a> devuelva <em>Blanks</em>:
Number of Previous values =
VAR __currentDate = data[Date]
RETURN
COALESCE(
COUNTROWS(
FILTER(
data,
data[Date] < __currentDate
)
),
0
)
', 'es') (Line: 118)
Drupal\filter\Element\ProcessedText::preRenderText(Array)
call_user_func_array(Array, Array) (Line: 101)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88)
__TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 46)
__TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 43)
__TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110)
__TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, ) (Line: 242)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
- Deprecated function: Creation of dynamic property Drupal\mysql\Driver\Database\mysql\Select::$alterMetaData is deprecated in Drupal\Core\Database\Query\Select->addMetaData() (line 178 of core/lib/Drupal/Core/Database/Query/Select.php).
Drupal\Core\Database\Query\Select->addMetaData('entity_type', 'file') (Line: 115)
Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80)
Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640)
Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63)
Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', 'insert-max_800_px-08e7a98a-1bb0-4e89-bba5-5402a6b3a4c0') (Line: 95)
Drupal\editor\Plugin\Filter\EditorFileReference->process('En este escenario partimos de la siguiente tabla de datos:
<a class="colorbox insert-colorbox" data-colorbox-gallery="gallery-node" data-insert-class="" data-insert-type="image" href="/sites/default/files/2021-06/dax-0110.jpg"></a>
Obsérvese que en la tabla las fechas se muestran ordenadas (de más antiguas a más modernas) para hacer más sencilla su interpretación, pero tengamos en mente que podría no ser así.
El objetivo es crear una columna calculada que nos indique, para cada fila, cuántas filas de la misma tabla contienen fechas anteriores a la de la fila siendo considerada (teniendo en cuenta, como se ha comentado, que las filas podrían estar no ordenadas según la fecha).
Como queremos añadir una columna calculada, se va a crear por defecto un contexto de fila para cada una de las filas evaluadas. Es decir, para la primera fila (la correspondiente al campo <em>Id</em> 1) se creará un contexto de fila en el que podremos acceder a los valores de sus campos, <em>Id</em> y <em>Date</em>. A partir del valor del campo <em>Date</em> querríamos filtrar la tabla de forma que solo se considerasen las filas con fechas anteriores y contar el número de filas resultantes.
En pseudo código sería algo así:
Number of Previous values =
COUNTROWS(
FILTER(
data,
data[Date] < fecha-de-la-fila-actual
)
)
Se ha utilizado la etiqueta <em>fecha-de-la-fila-actual</em> para hacer referencia al valor del campo <em>Date</em> de la fila siendo considerada.
La función <a href="/es/dax/function/filter">FILTER</a>, siendo un iterador, va a crear un nuevo contexto de fila en el que evaluar la condición para cada fila de la tabla <em>data</em>:
data[Date] < fecha-de-la-fila-actual
Lógicamente, el siguiente código no funcionaría:
Number of Previous values =
COUNTROWS(
FILTER(
data,
data[Date] < data[Date])
)
)
...pues dentro del contexto de fila creado por <a href="/es/dax/function/filter">FILTER</a>, el valor de <em>data[Date]</em> es el valor del campo <em>Date</em> de la fila que <a href="/es/dax/function/filter">FILTER</a> esté iterando. Lo que querríamos es que el valor de <em>fecha-de-la-fila-actual</em> fuese el definido en el contexto de fila "anterior", el creado por la columna calculada previo a la ejecución de la función <a href="/es/dax/function/filter">FILTER</a>.
Para ello tenemos dos soluciones:
La primera -la única existente hasta que se introdujeron las variables en DAX en 2015- es recurrir a la función <a href="/es/dax/function/earlier">EARLIER</a>. Esta función nos devuelve exactamente lo que queremos: el valor de un campo para un contexto de fila anterior (pudiendo indicarse cuántos contextos de fila hay que retroceder). Por ejemplo:
Number of Previous values =
COUNTROWS(
FILTER(
data,
data[Date] < EARLIER(data[Date], 1)
)
)
...devolvería el resultado que buscábamos:
<a class="colorbox insert-colorbox" data-colorbox-gallery="gallery-node" data-insert-class="" data-insert-type="image" href="/sites/default/files/2021-06/dax-0111.jpg"></a>
Vemos que, para la primera fila, la función devuelve un <em>Blank</em> pues no hay filas con fechas anteriores y la función <a href="/es/dax/function/countrows">COUNTROWS</a> devuelve este valor para tablas vacías. Podemos forzar que, en este caso, se devuelva un 0 usando la función <a href="/es/dax/function/coalesce">COALESCE</a>:
Number of Previous values =
COALESCE(
COUNTROWS(
FILTER(
data,
data[Date] < EARLIER(data[Date], 1)
)
),
0
)
<a class="colorbox insert-colorbox" data-colorbox-gallery="gallery-node" data-insert-class="" data-insert-type="image" href="/sites/default/files/2021-06/dax-0112.jpg"></a>
En este caso, como el contexto "anterior" es el único contexto previo, también podríamos usar la función <a href="/es/dax/function/earliest">EARLIEST</a> que nos devuelve el valor del campo indicado en el último contexto de fila existente:
Number of Previous values =
COALESCE(
COUNTROWS(
FILTER(
data,
data[Date] < EARLIEST(data[Date])
)
),
0
)
El segundo método es, precisamente, haciendo uso de variables, lo que resulta mucho más sencillo y fácilmente interpretable. Concretamente:
Number of Previous values =
VAR __currentDate = data[Date]
RETURN
COUNTROWS(
FILTER(
data,
data[Date] < __currentDate
)
)
En primer lugar creamos una variable (<em>__currentDate</em>) con la palabra reservada <a href="/es/dax/function/var">VAR</a>. Esta variable se va a crear en el contexto de evaluación existente que, en ese punto del código, es el contexto de fila creado por la columna calculada. Es decir, en este punto, el campo <em>data[Date]</em> toma el valor del campo <em>Date</em> en la fila que se esté evaluando.
Una vez registrado el valor de la fecha se ejecuta el filtrado de la tabla <em>data</em>. Tal y como se ha comentado, la función <a href="/es/dax/function/filter">FILTER</a> crea un nuevo contexto de fila en el que se recorre la tabla en cuestión comparando cada valor del campo <em>Date</em> -evaluado en el contexto de fila de la función <a href="/es/dax/function/filter">FILTER</a>- con el valor registrado en la variable <em>__currentDate</em> (valor que se registró en el contexto de fila de la columna calculada):
<a class="colorbox insert-colorbox" data-colorbox-gallery="gallery-node" data-insert-class="" data-insert-type="image" href="/sites/default/files/2021-06/dax-0113.jpg"></a>
Comprobamos que el resultado es el mismo que obtuvimos con la función <a href="/es/dax/function/earlier">EARLIER</a> pero más fácil de interpretar.
Una vez más, podríamos usar la función <a href="/es/dax/function/coalesce">COALESCE</a> para forzar ceros allí donde <a href="/es/dax/function/countrows">COUNTROWS</a> devuelva <em>Blanks</em>:
Number of Previous values =
VAR __currentDate = data[Date]
RETURN
COALESCE(
COUNTROWS(
FILTER(
data,
data[Date] < __currentDate
)
),
0
)
', 'es') (Line: 118)
Drupal\filter\Element\ProcessedText::preRenderText(Array)
call_user_func_array(Array, Array) (Line: 101)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88)
__TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 46)
__TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 43)
__TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110)
__TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, ) (Line: 242)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
- Deprecated function: Creation of dynamic property Drupal\mysql\Driver\Database\mysql\Select::$alterTags is deprecated in Drupal\Core\Database\Query\Select->addTag() (line 149 of core/lib/Drupal/Core/Database/Query/Select.php).
Drupal\Core\Database\Query\Select->addTag('entity_query') (Line: 147)
Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80)
Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640)
Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63)
Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', 'insert-max_800_px-08e7a98a-1bb0-4e89-bba5-5402a6b3a4c0') (Line: 95)
Drupal\editor\Plugin\Filter\EditorFileReference->process('En este escenario partimos de la siguiente tabla de datos:
<a class="colorbox insert-colorbox" data-colorbox-gallery="gallery-node" data-insert-class="" data-insert-type="image" href="/sites/default/files/2021-06/dax-0110.jpg"></a>
Obsérvese que en la tabla las fechas se muestran ordenadas (de más antiguas a más modernas) para hacer más sencilla su interpretación, pero tengamos en mente que podría no ser así.
El objetivo es crear una columna calculada que nos indique, para cada fila, cuántas filas de la misma tabla contienen fechas anteriores a la de la fila siendo considerada (teniendo en cuenta, como se ha comentado, que las filas podrían estar no ordenadas según la fecha).
Como queremos añadir una columna calculada, se va a crear por defecto un contexto de fila para cada una de las filas evaluadas. Es decir, para la primera fila (la correspondiente al campo <em>Id</em> 1) se creará un contexto de fila en el que podremos acceder a los valores de sus campos, <em>Id</em> y <em>Date</em>. A partir del valor del campo <em>Date</em> querríamos filtrar la tabla de forma que solo se considerasen las filas con fechas anteriores y contar el número de filas resultantes.
En pseudo código sería algo así:
Number of Previous values =
COUNTROWS(
FILTER(
data,
data[Date] < fecha-de-la-fila-actual
)
)
Se ha utilizado la etiqueta <em>fecha-de-la-fila-actual</em> para hacer referencia al valor del campo <em>Date</em> de la fila siendo considerada.
La función <a href="/es/dax/function/filter">FILTER</a>, siendo un iterador, va a crear un nuevo contexto de fila en el que evaluar la condición para cada fila de la tabla <em>data</em>:
data[Date] < fecha-de-la-fila-actual
Lógicamente, el siguiente código no funcionaría:
Number of Previous values =
COUNTROWS(
FILTER(
data,
data[Date] < data[Date])
)
)
...pues dentro del contexto de fila creado por <a href="/es/dax/function/filter">FILTER</a>, el valor de <em>data[Date]</em> es el valor del campo <em>Date</em> de la fila que <a href="/es/dax/function/filter">FILTER</a> esté iterando. Lo que querríamos es que el valor de <em>fecha-de-la-fila-actual</em> fuese el definido en el contexto de fila "anterior", el creado por la columna calculada previo a la ejecución de la función <a href="/es/dax/function/filter">FILTER</a>.
Para ello tenemos dos soluciones:
La primera -la única existente hasta que se introdujeron las variables en DAX en 2015- es recurrir a la función <a href="/es/dax/function/earlier">EARLIER</a>. Esta función nos devuelve exactamente lo que queremos: el valor de un campo para un contexto de fila anterior (pudiendo indicarse cuántos contextos de fila hay que retroceder). Por ejemplo:
Number of Previous values =
COUNTROWS(
FILTER(
data,
data[Date] < EARLIER(data[Date], 1)
)
)
...devolvería el resultado que buscábamos:
<a class="colorbox insert-colorbox" data-colorbox-gallery="gallery-node" data-insert-class="" data-insert-type="image" href="/sites/default/files/2021-06/dax-0111.jpg"></a>
Vemos que, para la primera fila, la función devuelve un <em>Blank</em> pues no hay filas con fechas anteriores y la función <a href="/es/dax/function/countrows">COUNTROWS</a> devuelve este valor para tablas vacías. Podemos forzar que, en este caso, se devuelva un 0 usando la función <a href="/es/dax/function/coalesce">COALESCE</a>:
Number of Previous values =
COALESCE(
COUNTROWS(
FILTER(
data,
data[Date] < EARLIER(data[Date], 1)
)
),
0
)
<a class="colorbox insert-colorbox" data-colorbox-gallery="gallery-node" data-insert-class="" data-insert-type="image" href="/sites/default/files/2021-06/dax-0112.jpg"></a>
En este caso, como el contexto "anterior" es el único contexto previo, también podríamos usar la función <a href="/es/dax/function/earliest">EARLIEST</a> que nos devuelve el valor del campo indicado en el último contexto de fila existente:
Number of Previous values =
COALESCE(
COUNTROWS(
FILTER(
data,
data[Date] < EARLIEST(data[Date])
)
),
0
)
El segundo método es, precisamente, haciendo uso de variables, lo que resulta mucho más sencillo y fácilmente interpretable. Concretamente:
Number of Previous values =
VAR __currentDate = data[Date]
RETURN
COUNTROWS(
FILTER(
data,
data[Date] < __currentDate
)
)
En primer lugar creamos una variable (<em>__currentDate</em>) con la palabra reservada <a href="/es/dax/function/var">VAR</a>. Esta variable se va a crear en el contexto de evaluación existente que, en ese punto del código, es el contexto de fila creado por la columna calculada. Es decir, en este punto, el campo <em>data[Date]</em> toma el valor del campo <em>Date</em> en la fila que se esté evaluando.
Una vez registrado el valor de la fecha se ejecuta el filtrado de la tabla <em>data</em>. Tal y como se ha comentado, la función <a href="/es/dax/function/filter">FILTER</a> crea un nuevo contexto de fila en el que se recorre la tabla en cuestión comparando cada valor del campo <em>Date</em> -evaluado en el contexto de fila de la función <a href="/es/dax/function/filter">FILTER</a>- con el valor registrado en la variable <em>__currentDate</em> (valor que se registró en el contexto de fila de la columna calculada):
<a class="colorbox insert-colorbox" data-colorbox-gallery="gallery-node" data-insert-class="" data-insert-type="image" href="/sites/default/files/2021-06/dax-0113.jpg"></a>
Comprobamos que el resultado es el mismo que obtuvimos con la función <a href="/es/dax/function/earlier">EARLIER</a> pero más fácil de interpretar.
Una vez más, podríamos usar la función <a href="/es/dax/function/coalesce">COALESCE</a> para forzar ceros allí donde <a href="/es/dax/function/countrows">COUNTROWS</a> devuelva <em>Blanks</em>:
Number of Previous values =
VAR __currentDate = data[Date]
RETURN
COALESCE(
COUNTROWS(
FILTER(
data,
data[Date] < __currentDate
)
),
0
)
', 'es') (Line: 118)
Drupal\filter\Element\ProcessedText::preRenderText(Array)
call_user_func_array(Array, Array) (Line: 101)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88)
__TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 46)
__TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 43)
__TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110)
__TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, ) (Line: 242)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
- Deprecated function: Creation of dynamic property Drupal\mysql\Driver\Database\mysql\Select::$alterMetaData is deprecated in Drupal\Core\Database\Query\Select->addMetaData() (line 178 of core/lib/Drupal/Core/Database/Query/Select.php).
Drupal\Core\Database\Query\Select->addMetaData('entity_type', 'file') (Line: 115)
Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80)
Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640)
Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63)
Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', 'insert-max_800_px-08e7a98a-1bb0-4e89-bba5-5402a6b3a4c0') (Line: 124)
Drupal\editor\Plugin\Filter\EditorFileReference->process('En este escenario partimos de la siguiente tabla de datos:
<a class="colorbox insert-colorbox" data-colorbox-gallery="gallery-node" data-insert-class="" data-insert-type="image" href="/sites/default/files/2021-06/dax-0110.jpg"></a>
Obsérvese que en la tabla las fechas se muestran ordenadas (de más antiguas a más modernas) para hacer más sencilla su interpretación, pero tengamos en mente que podría no ser así.
El objetivo es crear una columna calculada que nos indique, para cada fila, cuántas filas de la misma tabla contienen fechas anteriores a la de la fila siendo considerada (teniendo en cuenta, como se ha comentado, que las filas podrían estar no ordenadas según la fecha).
Como queremos añadir una columna calculada, se va a crear por defecto un contexto de fila para cada una de las filas evaluadas. Es decir, para la primera fila (la correspondiente al campo <em>Id</em> 1) se creará un contexto de fila en el que podremos acceder a los valores de sus campos, <em>Id</em> y <em>Date</em>. A partir del valor del campo <em>Date</em> querríamos filtrar la tabla de forma que solo se considerasen las filas con fechas anteriores y contar el número de filas resultantes.
En pseudo código sería algo así:
Number of Previous values =
COUNTROWS(
FILTER(
data,
data[Date] < fecha-de-la-fila-actual
)
)
Se ha utilizado la etiqueta <em>fecha-de-la-fila-actual</em> para hacer referencia al valor del campo <em>Date</em> de la fila siendo considerada.
La función <a href="/es/dax/function/filter">FILTER</a>, siendo un iterador, va a crear un nuevo contexto de fila en el que evaluar la condición para cada fila de la tabla <em>data</em>:
data[Date] < fecha-de-la-fila-actual
Lógicamente, el siguiente código no funcionaría:
Number of Previous values =
COUNTROWS(
FILTER(
data,
data[Date] < data[Date])
)
)
...pues dentro del contexto de fila creado por <a href="/es/dax/function/filter">FILTER</a>, el valor de <em>data[Date]</em> es el valor del campo <em>Date</em> de la fila que <a href="/es/dax/function/filter">FILTER</a> esté iterando. Lo que querríamos es que el valor de <em>fecha-de-la-fila-actual</em> fuese el definido en el contexto de fila "anterior", el creado por la columna calculada previo a la ejecución de la función <a href="/es/dax/function/filter">FILTER</a>.
Para ello tenemos dos soluciones:
La primera -la única existente hasta que se introdujeron las variables en DAX en 2015- es recurrir a la función <a href="/es/dax/function/earlier">EARLIER</a>. Esta función nos devuelve exactamente lo que queremos: el valor de un campo para un contexto de fila anterior (pudiendo indicarse cuántos contextos de fila hay que retroceder). Por ejemplo:
Number of Previous values =
COUNTROWS(
FILTER(
data,
data[Date] < EARLIER(data[Date], 1)
)
)
...devolvería el resultado que buscábamos:
<a class="colorbox insert-colorbox" data-colorbox-gallery="gallery-node" data-insert-class="" data-insert-type="image" href="/sites/default/files/2021-06/dax-0111.jpg"></a>
Vemos que, para la primera fila, la función devuelve un <em>Blank</em> pues no hay filas con fechas anteriores y la función <a href="/es/dax/function/countrows">COUNTROWS</a> devuelve este valor para tablas vacías. Podemos forzar que, en este caso, se devuelva un 0 usando la función <a href="/es/dax/function/coalesce">COALESCE</a>:
Number of Previous values =
COALESCE(
COUNTROWS(
FILTER(
data,
data[Date] < EARLIER(data[Date], 1)
)
),
0
)
<a class="colorbox insert-colorbox" data-colorbox-gallery="gallery-node" data-insert-class="" data-insert-type="image" href="/sites/default/files/2021-06/dax-0112.jpg"></a>
En este caso, como el contexto "anterior" es el único contexto previo, también podríamos usar la función <a href="/es/dax/function/earliest">EARLIEST</a> que nos devuelve el valor del campo indicado en el último contexto de fila existente:
Number of Previous values =
COALESCE(
COUNTROWS(
FILTER(
data,
data[Date] < EARLIEST(data[Date])
)
),
0
)
El segundo método es, precisamente, haciendo uso de variables, lo que resulta mucho más sencillo y fácilmente interpretable. Concretamente:
Number of Previous values =
VAR __currentDate = data[Date]
RETURN
COUNTROWS(
FILTER(
data,
data[Date] < __currentDate
)
)
En primer lugar creamos una variable (<em>__currentDate</em>) con la palabra reservada <a href="/es/dax/function/var">VAR</a>. Esta variable se va a crear en el contexto de evaluación existente que, en ese punto del código, es el contexto de fila creado por la columna calculada. Es decir, en este punto, el campo <em>data[Date]</em> toma el valor del campo <em>Date</em> en la fila que se esté evaluando.
Una vez registrado el valor de la fecha se ejecuta el filtrado de la tabla <em>data</em>. Tal y como se ha comentado, la función <a href="/es/dax/function/filter">FILTER</a> crea un nuevo contexto de fila en el que se recorre la tabla en cuestión comparando cada valor del campo <em>Date</em> -evaluado en el contexto de fila de la función <a href="/es/dax/function/filter">FILTER</a>- con el valor registrado en la variable <em>__currentDate</em> (valor que se registró en el contexto de fila de la columna calculada):
<a class="colorbox insert-colorbox" data-colorbox-gallery="gallery-node" data-insert-class="" data-insert-type="image" href="/sites/default/files/2021-06/dax-0113.jpg"></a>
Comprobamos que el resultado es el mismo que obtuvimos con la función <a href="/es/dax/function/earlier">EARLIER</a> pero más fácil de interpretar.
Una vez más, podríamos usar la función <a href="/es/dax/function/coalesce">COALESCE</a> para forzar ceros allí donde <a href="/es/dax/function/countrows">COUNTROWS</a> devuelva <em>Blanks</em>:
Number of Previous values =
VAR __currentDate = data[Date]
RETURN
COALESCE(
COUNTROWS(
FILTER(
data,
data[Date] < __currentDate
)
),
0
)
', 'es') (Line: 118)
Drupal\filter\Element\ProcessedText::preRenderText(Array)
call_user_func_array(Array, Array) (Line: 101)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88)
__TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 46)
__TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 43)
__TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110)
__TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, ) (Line: 242)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
- Deprecated function: Creation of dynamic property Drupal\mysql\Driver\Database\mysql\Select::$alterTags is deprecated in Drupal\Core\Database\Query\Select->addTag() (line 149 of core/lib/Drupal/Core/Database/Query/Select.php).
Drupal\Core\Database\Query\Select->addTag('entity_query') (Line: 147)
Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80)
Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640)
Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63)
Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', 'insert-max_800_px-08e7a98a-1bb0-4e89-bba5-5402a6b3a4c0') (Line: 124)
Drupal\editor\Plugin\Filter\EditorFileReference->process('En este escenario partimos de la siguiente tabla de datos:
<a class="colorbox insert-colorbox" data-colorbox-gallery="gallery-node" data-insert-class="" data-insert-type="image" href="/sites/default/files/2021-06/dax-0110.jpg"></a>
Obsérvese que en la tabla las fechas se muestran ordenadas (de más antiguas a más modernas) para hacer más sencilla su interpretación, pero tengamos en mente que podría no ser así.
El objetivo es crear una columna calculada que nos indique, para cada fila, cuántas filas de la misma tabla contienen fechas anteriores a la de la fila siendo considerada (teniendo en cuenta, como se ha comentado, que las filas podrían estar no ordenadas según la fecha).
Como queremos añadir una columna calculada, se va a crear por defecto un contexto de fila para cada una de las filas evaluadas. Es decir, para la primera fila (la correspondiente al campo <em>Id</em> 1) se creará un contexto de fila en el que podremos acceder a los valores de sus campos, <em>Id</em> y <em>Date</em>. A partir del valor del campo <em>Date</em> querríamos filtrar la tabla de forma que solo se considerasen las filas con fechas anteriores y contar el número de filas resultantes.
En pseudo código sería algo así:
Number of Previous values =
COUNTROWS(
FILTER(
data,
data[Date] < fecha-de-la-fila-actual
)
)
Se ha utilizado la etiqueta <em>fecha-de-la-fila-actual</em> para hacer referencia al valor del campo <em>Date</em> de la fila siendo considerada.
La función <a href="/es/dax/function/filter">FILTER</a>, siendo un iterador, va a crear un nuevo contexto de fila en el que evaluar la condición para cada fila de la tabla <em>data</em>:
data[Date] < fecha-de-la-fila-actual
Lógicamente, el siguiente código no funcionaría:
Number of Previous values =
COUNTROWS(
FILTER(
data,
data[Date] < data[Date])
)
)
...pues dentro del contexto de fila creado por <a href="/es/dax/function/filter">FILTER</a>, el valor de <em>data[Date]</em> es el valor del campo <em>Date</em> de la fila que <a href="/es/dax/function/filter">FILTER</a> esté iterando. Lo que querríamos es que el valor de <em>fecha-de-la-fila-actual</em> fuese el definido en el contexto de fila "anterior", el creado por la columna calculada previo a la ejecución de la función <a href="/es/dax/function/filter">FILTER</a>.
Para ello tenemos dos soluciones:
La primera -la única existente hasta que se introdujeron las variables en DAX en 2015- es recurrir a la función <a href="/es/dax/function/earlier">EARLIER</a>. Esta función nos devuelve exactamente lo que queremos: el valor de un campo para un contexto de fila anterior (pudiendo indicarse cuántos contextos de fila hay que retroceder). Por ejemplo:
Number of Previous values =
COUNTROWS(
FILTER(
data,
data[Date] < EARLIER(data[Date], 1)
)
)
...devolvería el resultado que buscábamos:
<a class="colorbox insert-colorbox" data-colorbox-gallery="gallery-node" data-insert-class="" data-insert-type="image" href="/sites/default/files/2021-06/dax-0111.jpg"></a>
Vemos que, para la primera fila, la función devuelve un <em>Blank</em> pues no hay filas con fechas anteriores y la función <a href="/es/dax/function/countrows">COUNTROWS</a> devuelve este valor para tablas vacías. Podemos forzar que, en este caso, se devuelva un 0 usando la función <a href="/es/dax/function/coalesce">COALESCE</a>:
Number of Previous values =
COALESCE(
COUNTROWS(
FILTER(
data,
data[Date] < EARLIER(data[Date], 1)
)
),
0
)
<a class="colorbox insert-colorbox" data-colorbox-gallery="gallery-node" data-insert-class="" data-insert-type="image" href="/sites/default/files/2021-06/dax-0112.jpg"></a>
En este caso, como el contexto "anterior" es el único contexto previo, también podríamos usar la función <a href="/es/dax/function/earliest">EARLIEST</a> que nos devuelve el valor del campo indicado en el último contexto de fila existente:
Number of Previous values =
COALESCE(
COUNTROWS(
FILTER(
data,
data[Date] < EARLIEST(data[Date])
)
),
0
)
El segundo método es, precisamente, haciendo uso de variables, lo que resulta mucho más sencillo y fácilmente interpretable. Concretamente:
Number of Previous values =
VAR __currentDate = data[Date]
RETURN
COUNTROWS(
FILTER(
data,
data[Date] < __currentDate
)
)
En primer lugar creamos una variable (<em>__currentDate</em>) con la palabra reservada <a href="/es/dax/function/var">VAR</a>. Esta variable se va a crear en el contexto de evaluación existente que, en ese punto del código, es el contexto de fila creado por la columna calculada. Es decir, en este punto, el campo <em>data[Date]</em> toma el valor del campo <em>Date</em> en la fila que se esté evaluando.
Una vez registrado el valor de la fecha se ejecuta el filtrado de la tabla <em>data</em>. Tal y como se ha comentado, la función <a href="/es/dax/function/filter">FILTER</a> crea un nuevo contexto de fila en el que se recorre la tabla en cuestión comparando cada valor del campo <em>Date</em> -evaluado en el contexto de fila de la función <a href="/es/dax/function/filter">FILTER</a>- con el valor registrado en la variable <em>__currentDate</em> (valor que se registró en el contexto de fila de la columna calculada):
<a class="colorbox insert-colorbox" data-colorbox-gallery="gallery-node" data-insert-class="" data-insert-type="image" href="/sites/default/files/2021-06/dax-0113.jpg"></a>
Comprobamos que el resultado es el mismo que obtuvimos con la función <a href="/es/dax/function/earlier">EARLIER</a> pero más fácil de interpretar.
Una vez más, podríamos usar la función <a href="/es/dax/function/coalesce">COALESCE</a> para forzar ceros allí donde <a href="/es/dax/function/countrows">COUNTROWS</a> devuelva <em>Blanks</em>:
Number of Previous values =
VAR __currentDate = data[Date]
RETURN
COALESCE(
COUNTROWS(
FILTER(
data,
data[Date] < __currentDate
)
),
0
)
', 'es') (Line: 118)
Drupal\filter\Element\ProcessedText::preRenderText(Array)
call_user_func_array(Array, Array) (Line: 101)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88)
__TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 46)
__TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 43)
__TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110)
__TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, ) (Line: 242)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
- Deprecated function: Creation of dynamic property Drupal\mysql\Driver\Database\mysql\Select::$alterMetaData is deprecated in Drupal\Core\Database\Query\Select->addMetaData() (line 178 of core/lib/Drupal/Core/Database/Query/Select.php).
Drupal\Core\Database\Query\Select->addMetaData('entity_type', 'file') (Line: 115)
Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80)
Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640)
Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63)
Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', 'insert-max_800_px-3cb7ced5-598b-408d-9d7d-d253ab959bba') (Line: 95)
Drupal\editor\Plugin\Filter\EditorFileReference->process('En este escenario partimos de la siguiente tabla de datos:
<a class="colorbox insert-colorbox" data-colorbox-gallery="gallery-node" data-insert-class="" data-insert-type="image" href="/sites/default/files/2021-06/dax-0110.jpg"></a>
Obsérvese que en la tabla las fechas se muestran ordenadas (de más antiguas a más modernas) para hacer más sencilla su interpretación, pero tengamos en mente que podría no ser así.
El objetivo es crear una columna calculada que nos indique, para cada fila, cuántas filas de la misma tabla contienen fechas anteriores a la de la fila siendo considerada (teniendo en cuenta, como se ha comentado, que las filas podrían estar no ordenadas según la fecha).
Como queremos añadir una columna calculada, se va a crear por defecto un contexto de fila para cada una de las filas evaluadas. Es decir, para la primera fila (la correspondiente al campo <em>Id</em> 1) se creará un contexto de fila en el que podremos acceder a los valores de sus campos, <em>Id</em> y <em>Date</em>. A partir del valor del campo <em>Date</em> querríamos filtrar la tabla de forma que solo se considerasen las filas con fechas anteriores y contar el número de filas resultantes.
En pseudo código sería algo así:
Number of Previous values =
COUNTROWS(
FILTER(
data,
data[Date] < fecha-de-la-fila-actual
)
)
Se ha utilizado la etiqueta <em>fecha-de-la-fila-actual</em> para hacer referencia al valor del campo <em>Date</em> de la fila siendo considerada.
La función <a href="/es/dax/function/filter">FILTER</a>, siendo un iterador, va a crear un nuevo contexto de fila en el que evaluar la condición para cada fila de la tabla <em>data</em>:
data[Date] < fecha-de-la-fila-actual
Lógicamente, el siguiente código no funcionaría:
Number of Previous values =
COUNTROWS(
FILTER(
data,
data[Date] < data[Date])
)
)
...pues dentro del contexto de fila creado por <a href="/es/dax/function/filter">FILTER</a>, el valor de <em>data[Date]</em> es el valor del campo <em>Date</em> de la fila que <a href="/es/dax/function/filter">FILTER</a> esté iterando. Lo que querríamos es que el valor de <em>fecha-de-la-fila-actual</em> fuese el definido en el contexto de fila "anterior", el creado por la columna calculada previo a la ejecución de la función <a href="/es/dax/function/filter">FILTER</a>.
Para ello tenemos dos soluciones:
La primera -la única existente hasta que se introdujeron las variables en DAX en 2015- es recurrir a la función <a href="/es/dax/function/earlier">EARLIER</a>. Esta función nos devuelve exactamente lo que queremos: el valor de un campo para un contexto de fila anterior (pudiendo indicarse cuántos contextos de fila hay que retroceder). Por ejemplo:
Number of Previous values =
COUNTROWS(
FILTER(
data,
data[Date] < EARLIER(data[Date], 1)
)
)
...devolvería el resultado que buscábamos:
<a class="colorbox insert-colorbox" data-colorbox-gallery="gallery-node" data-insert-class="" data-insert-type="image" href="/sites/default/files/2021-06/dax-0111.jpg"></a>
Vemos que, para la primera fila, la función devuelve un <em>Blank</em> pues no hay filas con fechas anteriores y la función <a href="/es/dax/function/countrows">COUNTROWS</a> devuelve este valor para tablas vacías. Podemos forzar que, en este caso, se devuelva un 0 usando la función <a href="/es/dax/function/coalesce">COALESCE</a>:
Number of Previous values =
COALESCE(
COUNTROWS(
FILTER(
data,
data[Date] < EARLIER(data[Date], 1)
)
),
0
)
<a class="colorbox insert-colorbox" data-colorbox-gallery="gallery-node" data-insert-class="" data-insert-type="image" href="/sites/default/files/2021-06/dax-0112.jpg"></a>
En este caso, como el contexto "anterior" es el único contexto previo, también podríamos usar la función <a href="/es/dax/function/earliest">EARLIEST</a> que nos devuelve el valor del campo indicado en el último contexto de fila existente:
Number of Previous values =
COALESCE(
COUNTROWS(
FILTER(
data,
data[Date] < EARLIEST(data[Date])
)
),
0
)
El segundo método es, precisamente, haciendo uso de variables, lo que resulta mucho más sencillo y fácilmente interpretable. Concretamente:
Number of Previous values =
VAR __currentDate = data[Date]
RETURN
COUNTROWS(
FILTER(
data,
data[Date] < __currentDate
)
)
En primer lugar creamos una variable (<em>__currentDate</em>) con la palabra reservada <a href="/es/dax/function/var">VAR</a>. Esta variable se va a crear en el contexto de evaluación existente que, en ese punto del código, es el contexto de fila creado por la columna calculada. Es decir, en este punto, el campo <em>data[Date]</em> toma el valor del campo <em>Date</em> en la fila que se esté evaluando.
Una vez registrado el valor de la fecha se ejecuta el filtrado de la tabla <em>data</em>. Tal y como se ha comentado, la función <a href="/es/dax/function/filter">FILTER</a> crea un nuevo contexto de fila en el que se recorre la tabla en cuestión comparando cada valor del campo <em>Date</em> -evaluado en el contexto de fila de la función <a href="/es/dax/function/filter">FILTER</a>- con el valor registrado en la variable <em>__currentDate</em> (valor que se registró en el contexto de fila de la columna calculada):
<a class="colorbox insert-colorbox" data-colorbox-gallery="gallery-node" data-insert-class="" data-insert-type="image" href="/sites/default/files/2021-06/dax-0113.jpg"></a>
Comprobamos que el resultado es el mismo que obtuvimos con la función <a href="/es/dax/function/earlier">EARLIER</a> pero más fácil de interpretar.
Una vez más, podríamos usar la función <a href="/es/dax/function/coalesce">COALESCE</a> para forzar ceros allí donde <a href="/es/dax/function/countrows">COUNTROWS</a> devuelva <em>Blanks</em>:
Number of Previous values =
VAR __currentDate = data[Date]
RETURN
COALESCE(
COUNTROWS(
FILTER(
data,
data[Date] < __currentDate
)
),
0
)
', 'es') (Line: 118)
Drupal\filter\Element\ProcessedText::preRenderText(Array)
call_user_func_array(Array, Array) (Line: 101)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88)
__TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 46)
__TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 43)
__TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110)
__TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, ) (Line: 242)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
- Deprecated function: Creation of dynamic property Drupal\mysql\Driver\Database\mysql\Select::$alterTags is deprecated in Drupal\Core\Database\Query\Select->addTag() (line 149 of core/lib/Drupal/Core/Database/Query/Select.php).
Drupal\Core\Database\Query\Select->addTag('entity_query') (Line: 147)
Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80)
Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640)
Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63)
Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', 'insert-max_800_px-3cb7ced5-598b-408d-9d7d-d253ab959bba') (Line: 95)
Drupal\editor\Plugin\Filter\EditorFileReference->process('En este escenario partimos de la siguiente tabla de datos:
<a class="colorbox insert-colorbox" data-colorbox-gallery="gallery-node" data-insert-class="" data-insert-type="image" href="/sites/default/files/2021-06/dax-0110.jpg"></a>
Obsérvese que en la tabla las fechas se muestran ordenadas (de más antiguas a más modernas) para hacer más sencilla su interpretación, pero tengamos en mente que podría no ser así.
El objetivo es crear una columna calculada que nos indique, para cada fila, cuántas filas de la misma tabla contienen fechas anteriores a la de la fila siendo considerada (teniendo en cuenta, como se ha comentado, que las filas podrían estar no ordenadas según la fecha).
Como queremos añadir una columna calculada, se va a crear por defecto un contexto de fila para cada una de las filas evaluadas. Es decir, para la primera fila (la correspondiente al campo <em>Id</em> 1) se creará un contexto de fila en el que podremos acceder a los valores de sus campos, <em>Id</em> y <em>Date</em>. A partir del valor del campo <em>Date</em> querríamos filtrar la tabla de forma que solo se considerasen las filas con fechas anteriores y contar el número de filas resultantes.
En pseudo código sería algo así:
Number of Previous values =
COUNTROWS(
FILTER(
data,
data[Date] < fecha-de-la-fila-actual
)
)
Se ha utilizado la etiqueta <em>fecha-de-la-fila-actual</em> para hacer referencia al valor del campo <em>Date</em> de la fila siendo considerada.
La función <a href="/es/dax/function/filter">FILTER</a>, siendo un iterador, va a crear un nuevo contexto de fila en el que evaluar la condición para cada fila de la tabla <em>data</em>:
data[Date] < fecha-de-la-fila-actual
Lógicamente, el siguiente código no funcionaría:
Number of Previous values =
COUNTROWS(
FILTER(
data,
data[Date] < data[Date])
)
)
...pues dentro del contexto de fila creado por <a href="/es/dax/function/filter">FILTER</a>, el valor de <em>data[Date]</em> es el valor del campo <em>Date</em> de la fila que <a href="/es/dax/function/filter">FILTER</a> esté iterando. Lo que querríamos es que el valor de <em>fecha-de-la-fila-actual</em> fuese el definido en el contexto de fila "anterior", el creado por la columna calculada previo a la ejecución de la función <a href="/es/dax/function/filter">FILTER</a>.
Para ello tenemos dos soluciones:
La primera -la única existente hasta que se introdujeron las variables en DAX en 2015- es recurrir a la función <a href="/es/dax/function/earlier">EARLIER</a>. Esta función nos devuelve exactamente lo que queremos: el valor de un campo para un contexto de fila anterior (pudiendo indicarse cuántos contextos de fila hay que retroceder). Por ejemplo:
Number of Previous values =
COUNTROWS(
FILTER(
data,
data[Date] < EARLIER(data[Date], 1)
)
)
...devolvería el resultado que buscábamos:
<a class="colorbox insert-colorbox" data-colorbox-gallery="gallery-node" data-insert-class="" data-insert-type="image" href="/sites/default/files/2021-06/dax-0111.jpg"></a>
Vemos que, para la primera fila, la función devuelve un <em>Blank</em> pues no hay filas con fechas anteriores y la función <a href="/es/dax/function/countrows">COUNTROWS</a> devuelve este valor para tablas vacías. Podemos forzar que, en este caso, se devuelva un 0 usando la función <a href="/es/dax/function/coalesce">COALESCE</a>:
Number of Previous values =
COALESCE(
COUNTROWS(
FILTER(
data,
data[Date] < EARLIER(data[Date], 1)
)
),
0
)
<a class="colorbox insert-colorbox" data-colorbox-gallery="gallery-node" data-insert-class="" data-insert-type="image" href="/sites/default/files/2021-06/dax-0112.jpg"></a>
En este caso, como el contexto "anterior" es el único contexto previo, también podríamos usar la función <a href="/es/dax/function/earliest">EARLIEST</a> que nos devuelve el valor del campo indicado en el último contexto de fila existente:
Number of Previous values =
COALESCE(
COUNTROWS(
FILTER(
data,
data[Date] < EARLIEST(data[Date])
)
),
0
)
El segundo método es, precisamente, haciendo uso de variables, lo que resulta mucho más sencillo y fácilmente interpretable. Concretamente:
Number of Previous values =
VAR __currentDate = data[Date]
RETURN
COUNTROWS(
FILTER(
data,
data[Date] < __currentDate
)
)
En primer lugar creamos una variable (<em>__currentDate</em>) con la palabra reservada <a href="/es/dax/function/var">VAR</a>. Esta variable se va a crear en el contexto de evaluación existente que, en ese punto del código, es el contexto de fila creado por la columna calculada. Es decir, en este punto, el campo <em>data[Date]</em> toma el valor del campo <em>Date</em> en la fila que se esté evaluando.
Una vez registrado el valor de la fecha se ejecuta el filtrado de la tabla <em>data</em>. Tal y como se ha comentado, la función <a href="/es/dax/function/filter">FILTER</a> crea un nuevo contexto de fila en el que se recorre la tabla en cuestión comparando cada valor del campo <em>Date</em> -evaluado en el contexto de fila de la función <a href="/es/dax/function/filter">FILTER</a>- con el valor registrado en la variable <em>__currentDate</em> (valor que se registró en el contexto de fila de la columna calculada):
<a class="colorbox insert-colorbox" data-colorbox-gallery="gallery-node" data-insert-class="" data-insert-type="image" href="/sites/default/files/2021-06/dax-0113.jpg"></a>
Comprobamos que el resultado es el mismo que obtuvimos con la función <a href="/es/dax/function/earlier">EARLIER</a> pero más fácil de interpretar.
Una vez más, podríamos usar la función <a href="/es/dax/function/coalesce">COALESCE</a> para forzar ceros allí donde <a href="/es/dax/function/countrows">COUNTROWS</a> devuelva <em>Blanks</em>:
Number of Previous values =
VAR __currentDate = data[Date]
RETURN
COALESCE(
COUNTROWS(
FILTER(
data,
data[Date] < __currentDate
)
),
0
)
', 'es') (Line: 118)
Drupal\filter\Element\ProcessedText::preRenderText(Array)
call_user_func_array(Array, Array) (Line: 101)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88)
__TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 46)
__TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 43)
__TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110)
__TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, ) (Line: 242)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
- Deprecated function: Creation of dynamic property Drupal\mysql\Driver\Database\mysql\Select::$alterMetaData is deprecated in Drupal\Core\Database\Query\Select->addMetaData() (line 178 of core/lib/Drupal/Core/Database/Query/Select.php).
Drupal\Core\Database\Query\Select->addMetaData('entity_type', 'file') (Line: 115)
Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80)
Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640)
Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63)
Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', 'insert-max_800_px-3cb7ced5-598b-408d-9d7d-d253ab959bba') (Line: 124)
Drupal\editor\Plugin\Filter\EditorFileReference->process('En este escenario partimos de la siguiente tabla de datos:
<a class="colorbox insert-colorbox" data-colorbox-gallery="gallery-node" data-insert-class="" data-insert-type="image" href="/sites/default/files/2021-06/dax-0110.jpg"></a>
Obsérvese que en la tabla las fechas se muestran ordenadas (de más antiguas a más modernas) para hacer más sencilla su interpretación, pero tengamos en mente que podría no ser así.
El objetivo es crear una columna calculada que nos indique, para cada fila, cuántas filas de la misma tabla contienen fechas anteriores a la de la fila siendo considerada (teniendo en cuenta, como se ha comentado, que las filas podrían estar no ordenadas según la fecha).
Como queremos añadir una columna calculada, se va a crear por defecto un contexto de fila para cada una de las filas evaluadas. Es decir, para la primera fila (la correspondiente al campo <em>Id</em> 1) se creará un contexto de fila en el que podremos acceder a los valores de sus campos, <em>Id</em> y <em>Date</em>. A partir del valor del campo <em>Date</em> querríamos filtrar la tabla de forma que solo se considerasen las filas con fechas anteriores y contar el número de filas resultantes.
En pseudo código sería algo así:
Number of Previous values =
COUNTROWS(
FILTER(
data,
data[Date] < fecha-de-la-fila-actual
)
)
Se ha utilizado la etiqueta <em>fecha-de-la-fila-actual</em> para hacer referencia al valor del campo <em>Date</em> de la fila siendo considerada.
La función <a href="/es/dax/function/filter">FILTER</a>, siendo un iterador, va a crear un nuevo contexto de fila en el que evaluar la condición para cada fila de la tabla <em>data</em>:
data[Date] < fecha-de-la-fila-actual
Lógicamente, el siguiente código no funcionaría:
Number of Previous values =
COUNTROWS(
FILTER(
data,
data[Date] < data[Date])
)
)
...pues dentro del contexto de fila creado por <a href="/es/dax/function/filter">FILTER</a>, el valor de <em>data[Date]</em> es el valor del campo <em>Date</em> de la fila que <a href="/es/dax/function/filter">FILTER</a> esté iterando. Lo que querríamos es que el valor de <em>fecha-de-la-fila-actual</em> fuese el definido en el contexto de fila "anterior", el creado por la columna calculada previo a la ejecución de la función <a href="/es/dax/function/filter">FILTER</a>.
Para ello tenemos dos soluciones:
La primera -la única existente hasta que se introdujeron las variables en DAX en 2015- es recurrir a la función <a href="/es/dax/function/earlier">EARLIER</a>. Esta función nos devuelve exactamente lo que queremos: el valor de un campo para un contexto de fila anterior (pudiendo indicarse cuántos contextos de fila hay que retroceder). Por ejemplo:
Number of Previous values =
COUNTROWS(
FILTER(
data,
data[Date] < EARLIER(data[Date], 1)
)
)
...devolvería el resultado que buscábamos:
<a class="colorbox insert-colorbox" data-colorbox-gallery="gallery-node" data-insert-class="" data-insert-type="image" href="/sites/default/files/2021-06/dax-0111.jpg"></a>
Vemos que, para la primera fila, la función devuelve un <em>Blank</em> pues no hay filas con fechas anteriores y la función <a href="/es/dax/function/countrows">COUNTROWS</a> devuelve este valor para tablas vacías. Podemos forzar que, en este caso, se devuelva un 0 usando la función <a href="/es/dax/function/coalesce">COALESCE</a>:
Number of Previous values =
COALESCE(
COUNTROWS(
FILTER(
data,
data[Date] < EARLIER(data[Date], 1)
)
),
0
)
<a class="colorbox insert-colorbox" data-colorbox-gallery="gallery-node" data-insert-class="" data-insert-type="image" href="/sites/default/files/2021-06/dax-0112.jpg"></a>
En este caso, como el contexto "anterior" es el único contexto previo, también podríamos usar la función <a href="/es/dax/function/earliest">EARLIEST</a> que nos devuelve el valor del campo indicado en el último contexto de fila existente:
Number of Previous values =
COALESCE(
COUNTROWS(
FILTER(
data,
data[Date] < EARLIEST(data[Date])
)
),
0
)
El segundo método es, precisamente, haciendo uso de variables, lo que resulta mucho más sencillo y fácilmente interpretable. Concretamente:
Number of Previous values =
VAR __currentDate = data[Date]
RETURN
COUNTROWS(
FILTER(
data,
data[Date] < __currentDate
)
)
En primer lugar creamos una variable (<em>__currentDate</em>) con la palabra reservada <a href="/es/dax/function/var">VAR</a>. Esta variable se va a crear en el contexto de evaluación existente que, en ese punto del código, es el contexto de fila creado por la columna calculada. Es decir, en este punto, el campo <em>data[Date]</em> toma el valor del campo <em>Date</em> en la fila que se esté evaluando.
Una vez registrado el valor de la fecha se ejecuta el filtrado de la tabla <em>data</em>. Tal y como se ha comentado, la función <a href="/es/dax/function/filter">FILTER</a> crea un nuevo contexto de fila en el que se recorre la tabla en cuestión comparando cada valor del campo <em>Date</em> -evaluado en el contexto de fila de la función <a href="/es/dax/function/filter">FILTER</a>- con el valor registrado en la variable <em>__currentDate</em> (valor que se registró en el contexto de fila de la columna calculada):
<a class="colorbox insert-colorbox" data-colorbox-gallery="gallery-node" data-insert-class="" data-insert-type="image" href="/sites/default/files/2021-06/dax-0113.jpg"></a>
Comprobamos que el resultado es el mismo que obtuvimos con la función <a href="/es/dax/function/earlier">EARLIER</a> pero más fácil de interpretar.
Una vez más, podríamos usar la función <a href="/es/dax/function/coalesce">COALESCE</a> para forzar ceros allí donde <a href="/es/dax/function/countrows">COUNTROWS</a> devuelva <em>Blanks</em>:
Number of Previous values =
VAR __currentDate = data[Date]
RETURN
COALESCE(
COUNTROWS(
FILTER(
data,
data[Date] < __currentDate
)
),
0
)
', 'es') (Line: 118)
Drupal\filter\Element\ProcessedText::preRenderText(Array)
call_user_func_array(Array, Array) (Line: 101)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88)
__TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 46)
__TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 43)
__TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110)
__TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, ) (Line: 242)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
- Deprecated function: Creation of dynamic property Drupal\mysql\Driver\Database\mysql\Select::$alterTags is deprecated in Drupal\Core\Database\Query\Select->addTag() (line 149 of core/lib/Drupal/Core/Database/Query/Select.php).
Drupal\Core\Database\Query\Select->addTag('entity_query') (Line: 147)
Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80)
Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640)
Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63)
Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', 'insert-max_800_px-3cb7ced5-598b-408d-9d7d-d253ab959bba') (Line: 124)
Drupal\editor\Plugin\Filter\EditorFileReference->process('En este escenario partimos de la siguiente tabla de datos:
<a class="colorbox insert-colorbox" data-colorbox-gallery="gallery-node" data-insert-class="" data-insert-type="image" href="/sites/default/files/2021-06/dax-0110.jpg"></a>
Obsérvese que en la tabla las fechas se muestran ordenadas (de más antiguas a más modernas) para hacer más sencilla su interpretación, pero tengamos en mente que podría no ser así.
El objetivo es crear una columna calculada que nos indique, para cada fila, cuántas filas de la misma tabla contienen fechas anteriores a la de la fila siendo considerada (teniendo en cuenta, como se ha comentado, que las filas podrían estar no ordenadas según la fecha).
Como queremos añadir una columna calculada, se va a crear por defecto un contexto de fila para cada una de las filas evaluadas. Es decir, para la primera fila (la correspondiente al campo <em>Id</em> 1) se creará un contexto de fila en el que podremos acceder a los valores de sus campos, <em>Id</em> y <em>Date</em>. A partir del valor del campo <em>Date</em> querríamos filtrar la tabla de forma que solo se considerasen las filas con fechas anteriores y contar el número de filas resultantes.
En pseudo código sería algo así:
Number of Previous values =
COUNTROWS(
FILTER(
data,
data[Date] < fecha-de-la-fila-actual
)
)
Se ha utilizado la etiqueta <em>fecha-de-la-fila-actual</em> para hacer referencia al valor del campo <em>Date</em> de la fila siendo considerada.
La función <a href="/es/dax/function/filter">FILTER</a>, siendo un iterador, va a crear un nuevo contexto de fila en el que evaluar la condición para cada fila de la tabla <em>data</em>:
data[Date] < fecha-de-la-fila-actual
Lógicamente, el siguiente código no funcionaría:
Number of Previous values =
COUNTROWS(
FILTER(
data,
data[Date] < data[Date])
)
)
...pues dentro del contexto de fila creado por <a href="/es/dax/function/filter">FILTER</a>, el valor de <em>data[Date]</em> es el valor del campo <em>Date</em> de la fila que <a href="/es/dax/function/filter">FILTER</a> esté iterando. Lo que querríamos es que el valor de <em>fecha-de-la-fila-actual</em> fuese el definido en el contexto de fila "anterior", el creado por la columna calculada previo a la ejecución de la función <a href="/es/dax/function/filter">FILTER</a>.
Para ello tenemos dos soluciones:
La primera -la única existente hasta que se introdujeron las variables en DAX en 2015- es recurrir a la función <a href="/es/dax/function/earlier">EARLIER</a>. Esta función nos devuelve exactamente lo que queremos: el valor de un campo para un contexto de fila anterior (pudiendo indicarse cuántos contextos de fila hay que retroceder). Por ejemplo:
Number of Previous values =
COUNTROWS(
FILTER(
data,
data[Date] < EARLIER(data[Date], 1)
)
)
...devolvería el resultado que buscábamos:
<a class="colorbox insert-colorbox" data-colorbox-gallery="gallery-node" data-insert-class="" data-insert-type="image" href="/sites/default/files/2021-06/dax-0111.jpg"></a>
Vemos que, para la primera fila, la función devuelve un <em>Blank</em> pues no hay filas con fechas anteriores y la función <a href="/es/dax/function/countrows">COUNTROWS</a> devuelve este valor para tablas vacías. Podemos forzar que, en este caso, se devuelva un 0 usando la función <a href="/es/dax/function/coalesce">COALESCE</a>:
Number of Previous values =
COALESCE(
COUNTROWS(
FILTER(
data,
data[Date] < EARLIER(data[Date], 1)
)
),
0
)
<a class="colorbox insert-colorbox" data-colorbox-gallery="gallery-node" data-insert-class="" data-insert-type="image" href="/sites/default/files/2021-06/dax-0112.jpg"></a>
En este caso, como el contexto "anterior" es el único contexto previo, también podríamos usar la función <a href="/es/dax/function/earliest">EARLIEST</a> que nos devuelve el valor del campo indicado en el último contexto de fila existente:
Number of Previous values =
COALESCE(
COUNTROWS(
FILTER(
data,
data[Date] < EARLIEST(data[Date])
)
),
0
)
El segundo método es, precisamente, haciendo uso de variables, lo que resulta mucho más sencillo y fácilmente interpretable. Concretamente:
Number of Previous values =
VAR __currentDate = data[Date]
RETURN
COUNTROWS(
FILTER(
data,
data[Date] < __currentDate
)
)
En primer lugar creamos una variable (<em>__currentDate</em>) con la palabra reservada <a href="/es/dax/function/var">VAR</a>. Esta variable se va a crear en el contexto de evaluación existente que, en ese punto del código, es el contexto de fila creado por la columna calculada. Es decir, en este punto, el campo <em>data[Date]</em> toma el valor del campo <em>Date</em> en la fila que se esté evaluando.
Una vez registrado el valor de la fecha se ejecuta el filtrado de la tabla <em>data</em>. Tal y como se ha comentado, la función <a href="/es/dax/function/filter">FILTER</a> crea un nuevo contexto de fila en el que se recorre la tabla en cuestión comparando cada valor del campo <em>Date</em> -evaluado en el contexto de fila de la función <a href="/es/dax/function/filter">FILTER</a>- con el valor registrado en la variable <em>__currentDate</em> (valor que se registró en el contexto de fila de la columna calculada):
<a class="colorbox insert-colorbox" data-colorbox-gallery="gallery-node" data-insert-class="" data-insert-type="image" href="/sites/default/files/2021-06/dax-0113.jpg"></a>
Comprobamos que el resultado es el mismo que obtuvimos con la función <a href="/es/dax/function/earlier">EARLIER</a> pero más fácil de interpretar.
Una vez más, podríamos usar la función <a href="/es/dax/function/coalesce">COALESCE</a> para forzar ceros allí donde <a href="/es/dax/function/countrows">COUNTROWS</a> devuelva <em>Blanks</em>:
Number of Previous values =
VAR __currentDate = data[Date]
RETURN
COALESCE(
COUNTROWS(
FILTER(
data,
data[Date] < __currentDate
)
),
0
)
', 'es') (Line: 118)
Drupal\filter\Element\ProcessedText::preRenderText(Array)
call_user_func_array(Array, Array) (Line: 101)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88)
__TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 46)
__TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 43)
__TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110)
__TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, ) (Line: 242)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
- Deprecated function: Creation of dynamic property Drupal\mysql\Driver\Database\mysql\Select::$alterMetaData is deprecated in Drupal\Core\Database\Query\Select->addMetaData() (line 178 of core/lib/Drupal/Core/Database/Query/Select.php).
Drupal\Core\Database\Query\Select->addMetaData('entity_type', 'file') (Line: 115)
Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80)
Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640)
Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63)
Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', '67229f85-0b0f-4009-b1d9-384ec4ac3a8f') (Line: 95)
Drupal\editor\Plugin\Filter\EditorFileReference->process('Partimos de una tabla de ventas ("<em>Movements</em>") en la que figura la fecha de venta, el identificador del usuario y el importe de venta:
Nuestro objetivo es añadir una nueva columna en la que se muestre la última compra del mismo cliente. Al recorrerse la tabla creándose el nuevo campo se creará para cada fila el contexto de fila asociado, lo que nos da acceso a los campos de la fila. Concretamente, la función <a href="/dax/function/earlier">EARLIER</a> nos permite acceder al identificador del cliente y a la fecha, de forma que podemos calcular el subconjunto de la tabla que contiene las compras del cliente actual anteriores a la fecha actual con la siguiente expresión:
FILTER(
Movements;
Movements[Customer Id] = EARLIER(Movements[Customer Id]) &&
Movements[Order Date] < EARLIER(Movements[Order Date])
)
Una vez calculado este subconjunto, podemos extraer la última fecha muy fácilmente usando la función <a href="/dax/function/lastdate">LASTDATE</a>, función que devuelve una tabla con la última fecha del contexto actual. Usada como argumento de <a href="/dax/function/calculate">CALCULATE</a> y añadiendo como filtro el subconjunto calculado, podemos extraer la última fecha del conjunto (es decir, la última fecha de compra antes de la actual):
Last Purchase =
CALCULATE(
LASTDATE(Movements[Order Date]);
FILTER(
Movements;
Movements[Customer Id] = EARLIER(Movements[Customer Id]) &&
Movements[Order Date] < EARLIER(Movements[Order Date])
)
)
Recordemos que, aunque la función LASTDATE devuelve una tabla, el resultado puede ser usado como un escalar allí donde se requiera una simple fecha. El resultado obtenido es el siguiente:
Podemos confirmar que el cálculo es correcto si llevamos a una visualización tipo tabla el identificador de usuario, el campo <em>Order Date</em> y el campo recién creado <em>Last Purchase</em>, filtrando el identificador de usuario (usando una segmentación, por ejemplo) y ordenando la tabla creada según el campo <em>Order Date</em>:
Vemos cómo la fecha de última compra coincide con la anterior.
', 'es') (Line: 118)
Drupal\filter\Element\ProcessedText::preRenderText(Array)
call_user_func_array(Array, Array) (Line: 101)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88)
__TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 46)
__TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 43)
__TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110)
__TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, ) (Line: 242)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
- Deprecated function: Creation of dynamic property Drupal\mysql\Driver\Database\mysql\Select::$alterTags is deprecated in Drupal\Core\Database\Query\Select->addTag() (line 149 of core/lib/Drupal/Core/Database/Query/Select.php).
Drupal\Core\Database\Query\Select->addTag('entity_query') (Line: 147)
Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80)
Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640)
Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63)
Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', '67229f85-0b0f-4009-b1d9-384ec4ac3a8f') (Line: 95)
Drupal\editor\Plugin\Filter\EditorFileReference->process('Partimos de una tabla de ventas ("<em>Movements</em>") en la que figura la fecha de venta, el identificador del usuario y el importe de venta:
Nuestro objetivo es añadir una nueva columna en la que se muestre la última compra del mismo cliente. Al recorrerse la tabla creándose el nuevo campo se creará para cada fila el contexto de fila asociado, lo que nos da acceso a los campos de la fila. Concretamente, la función <a href="/dax/function/earlier">EARLIER</a> nos permite acceder al identificador del cliente y a la fecha, de forma que podemos calcular el subconjunto de la tabla que contiene las compras del cliente actual anteriores a la fecha actual con la siguiente expresión:
FILTER(
Movements;
Movements[Customer Id] = EARLIER(Movements[Customer Id]) &&
Movements[Order Date] < EARLIER(Movements[Order Date])
)
Una vez calculado este subconjunto, podemos extraer la última fecha muy fácilmente usando la función <a href="/dax/function/lastdate">LASTDATE</a>, función que devuelve una tabla con la última fecha del contexto actual. Usada como argumento de <a href="/dax/function/calculate">CALCULATE</a> y añadiendo como filtro el subconjunto calculado, podemos extraer la última fecha del conjunto (es decir, la última fecha de compra antes de la actual):
Last Purchase =
CALCULATE(
LASTDATE(Movements[Order Date]);
FILTER(
Movements;
Movements[Customer Id] = EARLIER(Movements[Customer Id]) &&
Movements[Order Date] < EARLIER(Movements[Order Date])
)
)
Recordemos que, aunque la función LASTDATE devuelve una tabla, el resultado puede ser usado como un escalar allí donde se requiera una simple fecha. El resultado obtenido es el siguiente:
Podemos confirmar que el cálculo es correcto si llevamos a una visualización tipo tabla el identificador de usuario, el campo <em>Order Date</em> y el campo recién creado <em>Last Purchase</em>, filtrando el identificador de usuario (usando una segmentación, por ejemplo) y ordenando la tabla creada según el campo <em>Order Date</em>:
Vemos cómo la fecha de última compra coincide con la anterior.
', 'es') (Line: 118)
Drupal\filter\Element\ProcessedText::preRenderText(Array)
call_user_func_array(Array, Array) (Line: 101)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88)
__TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 46)
__TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 43)
__TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110)
__TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, ) (Line: 242)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
- Deprecated function: Creation of dynamic property Drupal\mysql\Driver\Database\mysql\Select::$alterMetaData is deprecated in Drupal\Core\Database\Query\Select->addMetaData() (line 178 of core/lib/Drupal/Core/Database/Query/Select.php).
Drupal\Core\Database\Query\Select->addMetaData('entity_type', 'file') (Line: 115)
Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80)
Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640)
Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63)
Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', '67229f85-0b0f-4009-b1d9-384ec4ac3a8f') (Line: 124)
Drupal\editor\Plugin\Filter\EditorFileReference->process('Partimos de una tabla de ventas ("<em>Movements</em>") en la que figura la fecha de venta, el identificador del usuario y el importe de venta:
Nuestro objetivo es añadir una nueva columna en la que se muestre la última compra del mismo cliente. Al recorrerse la tabla creándose el nuevo campo se creará para cada fila el contexto de fila asociado, lo que nos da acceso a los campos de la fila. Concretamente, la función <a href="/dax/function/earlier">EARLIER</a> nos permite acceder al identificador del cliente y a la fecha, de forma que podemos calcular el subconjunto de la tabla que contiene las compras del cliente actual anteriores a la fecha actual con la siguiente expresión:
FILTER(
Movements;
Movements[Customer Id] = EARLIER(Movements[Customer Id]) &&
Movements[Order Date] < EARLIER(Movements[Order Date])
)
Una vez calculado este subconjunto, podemos extraer la última fecha muy fácilmente usando la función <a href="/dax/function/lastdate">LASTDATE</a>, función que devuelve una tabla con la última fecha del contexto actual. Usada como argumento de <a href="/dax/function/calculate">CALCULATE</a> y añadiendo como filtro el subconjunto calculado, podemos extraer la última fecha del conjunto (es decir, la última fecha de compra antes de la actual):
Last Purchase =
CALCULATE(
LASTDATE(Movements[Order Date]);
FILTER(
Movements;
Movements[Customer Id] = EARLIER(Movements[Customer Id]) &&
Movements[Order Date] < EARLIER(Movements[Order Date])
)
)
Recordemos que, aunque la función LASTDATE devuelve una tabla, el resultado puede ser usado como un escalar allí donde se requiera una simple fecha. El resultado obtenido es el siguiente:
Podemos confirmar que el cálculo es correcto si llevamos a una visualización tipo tabla el identificador de usuario, el campo <em>Order Date</em> y el campo recién creado <em>Last Purchase</em>, filtrando el identificador de usuario (usando una segmentación, por ejemplo) y ordenando la tabla creada según el campo <em>Order Date</em>:
Vemos cómo la fecha de última compra coincide con la anterior.
', 'es') (Line: 118)
Drupal\filter\Element\ProcessedText::preRenderText(Array)
call_user_func_array(Array, Array) (Line: 101)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88)
__TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 46)
__TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 43)
__TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110)
__TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, ) (Line: 242)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
- Deprecated function: Creation of dynamic property Drupal\mysql\Driver\Database\mysql\Select::$alterTags is deprecated in Drupal\Core\Database\Query\Select->addTag() (line 149 of core/lib/Drupal/Core/Database/Query/Select.php).
Drupal\Core\Database\Query\Select->addTag('entity_query') (Line: 147)
Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80)
Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640)
Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63)
Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', '67229f85-0b0f-4009-b1d9-384ec4ac3a8f') (Line: 124)
Drupal\editor\Plugin\Filter\EditorFileReference->process('Partimos de una tabla de ventas ("<em>Movements</em>") en la que figura la fecha de venta, el identificador del usuario y el importe de venta:
Nuestro objetivo es añadir una nueva columna en la que se muestre la última compra del mismo cliente. Al recorrerse la tabla creándose el nuevo campo se creará para cada fila el contexto de fila asociado, lo que nos da acceso a los campos de la fila. Concretamente, la función <a href="/dax/function/earlier">EARLIER</a> nos permite acceder al identificador del cliente y a la fecha, de forma que podemos calcular el subconjunto de la tabla que contiene las compras del cliente actual anteriores a la fecha actual con la siguiente expresión:
FILTER(
Movements;
Movements[Customer Id] = EARLIER(Movements[Customer Id]) &&
Movements[Order Date] < EARLIER(Movements[Order Date])
)
Una vez calculado este subconjunto, podemos extraer la última fecha muy fácilmente usando la función <a href="/dax/function/lastdate">LASTDATE</a>, función que devuelve una tabla con la última fecha del contexto actual. Usada como argumento de <a href="/dax/function/calculate">CALCULATE</a> y añadiendo como filtro el subconjunto calculado, podemos extraer la última fecha del conjunto (es decir, la última fecha de compra antes de la actual):
Last Purchase =
CALCULATE(
LASTDATE(Movements[Order Date]);
FILTER(
Movements;
Movements[Customer Id] = EARLIER(Movements[Customer Id]) &&
Movements[Order Date] < EARLIER(Movements[Order Date])
)
)
Recordemos que, aunque la función LASTDATE devuelve una tabla, el resultado puede ser usado como un escalar allí donde se requiera una simple fecha. El resultado obtenido es el siguiente:
Podemos confirmar que el cálculo es correcto si llevamos a una visualización tipo tabla el identificador de usuario, el campo <em>Order Date</em> y el campo recién creado <em>Last Purchase</em>, filtrando el identificador de usuario (usando una segmentación, por ejemplo) y ordenando la tabla creada según el campo <em>Order Date</em>:
Vemos cómo la fecha de última compra coincide con la anterior.
', 'es') (Line: 118)
Drupal\filter\Element\ProcessedText::preRenderText(Array)
call_user_func_array(Array, Array) (Line: 101)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88)
__TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 46)
__TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 43)
__TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110)
__TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, ) (Line: 242)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
- Deprecated function: Creation of dynamic property Drupal\mysql\Driver\Database\mysql\Select::$alterMetaData is deprecated in Drupal\Core\Database\Query\Select->addMetaData() (line 178 of core/lib/Drupal/Core/Database/Query/Select.php).
Drupal\Core\Database\Query\Select->addMetaData('entity_type', 'file') (Line: 115)
Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80)
Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640)
Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63)
Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', '89501d32-a9ec-4177-a5ac-18dcba38df11') (Line: 95)
Drupal\editor\Plugin\Filter\EditorFileReference->process('Partimos de una tabla de ventas ("<em>Movements</em>") en la que figura la fecha de venta, el identificador del usuario y el importe de venta:
Nuestro objetivo es añadir una nueva columna en la que se muestre la última compra del mismo cliente. Al recorrerse la tabla creándose el nuevo campo se creará para cada fila el contexto de fila asociado, lo que nos da acceso a los campos de la fila. Concretamente, la función <a href="/dax/function/earlier">EARLIER</a> nos permite acceder al identificador del cliente y a la fecha, de forma que podemos calcular el subconjunto de la tabla que contiene las compras del cliente actual anteriores a la fecha actual con la siguiente expresión:
FILTER(
Movements;
Movements[Customer Id] = EARLIER(Movements[Customer Id]) &&
Movements[Order Date] < EARLIER(Movements[Order Date])
)
Una vez calculado este subconjunto, podemos extraer la última fecha muy fácilmente usando la función <a href="/dax/function/lastdate">LASTDATE</a>, función que devuelve una tabla con la última fecha del contexto actual. Usada como argumento de <a href="/dax/function/calculate">CALCULATE</a> y añadiendo como filtro el subconjunto calculado, podemos extraer la última fecha del conjunto (es decir, la última fecha de compra antes de la actual):
Last Purchase =
CALCULATE(
LASTDATE(Movements[Order Date]);
FILTER(
Movements;
Movements[Customer Id] = EARLIER(Movements[Customer Id]) &&
Movements[Order Date] < EARLIER(Movements[Order Date])
)
)
Recordemos que, aunque la función LASTDATE devuelve una tabla, el resultado puede ser usado como un escalar allí donde se requiera una simple fecha. El resultado obtenido es el siguiente:
Podemos confirmar que el cálculo es correcto si llevamos a una visualización tipo tabla el identificador de usuario, el campo <em>Order Date</em> y el campo recién creado <em>Last Purchase</em>, filtrando el identificador de usuario (usando una segmentación, por ejemplo) y ordenando la tabla creada según el campo <em>Order Date</em>:
Vemos cómo la fecha de última compra coincide con la anterior.
', 'es') (Line: 118)
Drupal\filter\Element\ProcessedText::preRenderText(Array)
call_user_func_array(Array, Array) (Line: 101)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88)
__TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 46)
__TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 43)
__TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110)
__TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, ) (Line: 242)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
- Deprecated function: Creation of dynamic property Drupal\mysql\Driver\Database\mysql\Select::$alterTags is deprecated in Drupal\Core\Database\Query\Select->addTag() (line 149 of core/lib/Drupal/Core/Database/Query/Select.php).
Drupal\Core\Database\Query\Select->addTag('entity_query') (Line: 147)
Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80)
Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640)
Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63)
Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', '89501d32-a9ec-4177-a5ac-18dcba38df11') (Line: 95)
Drupal\editor\Plugin\Filter\EditorFileReference->process('Partimos de una tabla de ventas ("<em>Movements</em>") en la que figura la fecha de venta, el identificador del usuario y el importe de venta:
Nuestro objetivo es añadir una nueva columna en la que se muestre la última compra del mismo cliente. Al recorrerse la tabla creándose el nuevo campo se creará para cada fila el contexto de fila asociado, lo que nos da acceso a los campos de la fila. Concretamente, la función <a href="/dax/function/earlier">EARLIER</a> nos permite acceder al identificador del cliente y a la fecha, de forma que podemos calcular el subconjunto de la tabla que contiene las compras del cliente actual anteriores a la fecha actual con la siguiente expresión:
FILTER(
Movements;
Movements[Customer Id] = EARLIER(Movements[Customer Id]) &&
Movements[Order Date] < EARLIER(Movements[Order Date])
)
Una vez calculado este subconjunto, podemos extraer la última fecha muy fácilmente usando la función <a href="/dax/function/lastdate">LASTDATE</a>, función que devuelve una tabla con la última fecha del contexto actual. Usada como argumento de <a href="/dax/function/calculate">CALCULATE</a> y añadiendo como filtro el subconjunto calculado, podemos extraer la última fecha del conjunto (es decir, la última fecha de compra antes de la actual):
Last Purchase =
CALCULATE(
LASTDATE(Movements[Order Date]);
FILTER(
Movements;
Movements[Customer Id] = EARLIER(Movements[Customer Id]) &&
Movements[Order Date] < EARLIER(Movements[Order Date])
)
)
Recordemos que, aunque la función LASTDATE devuelve una tabla, el resultado puede ser usado como un escalar allí donde se requiera una simple fecha. El resultado obtenido es el siguiente:
Podemos confirmar que el cálculo es correcto si llevamos a una visualización tipo tabla el identificador de usuario, el campo <em>Order Date</em> y el campo recién creado <em>Last Purchase</em>, filtrando el identificador de usuario (usando una segmentación, por ejemplo) y ordenando la tabla creada según el campo <em>Order Date</em>:
Vemos cómo la fecha de última compra coincide con la anterior.
', 'es') (Line: 118)
Drupal\filter\Element\ProcessedText::preRenderText(Array)
call_user_func_array(Array, Array) (Line: 101)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88)
__TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 46)
__TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 43)
__TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110)
__TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, ) (Line: 242)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
- Deprecated function: Creation of dynamic property Drupal\mysql\Driver\Database\mysql\Select::$alterMetaData is deprecated in Drupal\Core\Database\Query\Select->addMetaData() (line 178 of core/lib/Drupal/Core/Database/Query/Select.php).
Drupal\Core\Database\Query\Select->addMetaData('entity_type', 'file') (Line: 115)
Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80)
Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640)
Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63)
Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', '89501d32-a9ec-4177-a5ac-18dcba38df11') (Line: 124)
Drupal\editor\Plugin\Filter\EditorFileReference->process('Partimos de una tabla de ventas ("<em>Movements</em>") en la que figura la fecha de venta, el identificador del usuario y el importe de venta:
Nuestro objetivo es añadir una nueva columna en la que se muestre la última compra del mismo cliente. Al recorrerse la tabla creándose el nuevo campo se creará para cada fila el contexto de fila asociado, lo que nos da acceso a los campos de la fila. Concretamente, la función <a href="/dax/function/earlier">EARLIER</a> nos permite acceder al identificador del cliente y a la fecha, de forma que podemos calcular el subconjunto de la tabla que contiene las compras del cliente actual anteriores a la fecha actual con la siguiente expresión:
FILTER(
Movements;
Movements[Customer Id] = EARLIER(Movements[Customer Id]) &&
Movements[Order Date] < EARLIER(Movements[Order Date])
)
Una vez calculado este subconjunto, podemos extraer la última fecha muy fácilmente usando la función <a href="/dax/function/lastdate">LASTDATE</a>, función que devuelve una tabla con la última fecha del contexto actual. Usada como argumento de <a href="/dax/function/calculate">CALCULATE</a> y añadiendo como filtro el subconjunto calculado, podemos extraer la última fecha del conjunto (es decir, la última fecha de compra antes de la actual):
Last Purchase =
CALCULATE(
LASTDATE(Movements[Order Date]);
FILTER(
Movements;
Movements[Customer Id] = EARLIER(Movements[Customer Id]) &&
Movements[Order Date] < EARLIER(Movements[Order Date])
)
)
Recordemos que, aunque la función LASTDATE devuelve una tabla, el resultado puede ser usado como un escalar allí donde se requiera una simple fecha. El resultado obtenido es el siguiente:
Podemos confirmar que el cálculo es correcto si llevamos a una visualización tipo tabla el identificador de usuario, el campo <em>Order Date</em> y el campo recién creado <em>Last Purchase</em>, filtrando el identificador de usuario (usando una segmentación, por ejemplo) y ordenando la tabla creada según el campo <em>Order Date</em>:
Vemos cómo la fecha de última compra coincide con la anterior.
', 'es') (Line: 118)
Drupal\filter\Element\ProcessedText::preRenderText(Array)
call_user_func_array(Array, Array) (Line: 101)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88)
__TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 46)
__TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 43)
__TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110)
__TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, ) (Line: 242)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
- Deprecated function: Creation of dynamic property Drupal\mysql\Driver\Database\mysql\Select::$alterTags is deprecated in Drupal\Core\Database\Query\Select->addTag() (line 149 of core/lib/Drupal/Core/Database/Query/Select.php).
Drupal\Core\Database\Query\Select->addTag('entity_query') (Line: 147)
Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80)
Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640)
Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63)
Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', '89501d32-a9ec-4177-a5ac-18dcba38df11') (Line: 124)
Drupal\editor\Plugin\Filter\EditorFileReference->process('Partimos de una tabla de ventas ("<em>Movements</em>") en la que figura la fecha de venta, el identificador del usuario y el importe de venta:
Nuestro objetivo es añadir una nueva columna en la que se muestre la última compra del mismo cliente. Al recorrerse la tabla creándose el nuevo campo se creará para cada fila el contexto de fila asociado, lo que nos da acceso a los campos de la fila. Concretamente, la función <a href="/dax/function/earlier">EARLIER</a> nos permite acceder al identificador del cliente y a la fecha, de forma que podemos calcular el subconjunto de la tabla que contiene las compras del cliente actual anteriores a la fecha actual con la siguiente expresión:
FILTER(
Movements;
Movements[Customer Id] = EARLIER(Movements[Customer Id]) &&
Movements[Order Date] < EARLIER(Movements[Order Date])
)
Una vez calculado este subconjunto, podemos extraer la última fecha muy fácilmente usando la función <a href="/dax/function/lastdate">LASTDATE</a>, función que devuelve una tabla con la última fecha del contexto actual. Usada como argumento de <a href="/dax/function/calculate">CALCULATE</a> y añadiendo como filtro el subconjunto calculado, podemos extraer la última fecha del conjunto (es decir, la última fecha de compra antes de la actual):
Last Purchase =
CALCULATE(
LASTDATE(Movements[Order Date]);
FILTER(
Movements;
Movements[Customer Id] = EARLIER(Movements[Customer Id]) &&
Movements[Order Date] < EARLIER(Movements[Order Date])
)
)
Recordemos que, aunque la función LASTDATE devuelve una tabla, el resultado puede ser usado como un escalar allí donde se requiera una simple fecha. El resultado obtenido es el siguiente:
Podemos confirmar que el cálculo es correcto si llevamos a una visualización tipo tabla el identificador de usuario, el campo <em>Order Date</em> y el campo recién creado <em>Last Purchase</em>, filtrando el identificador de usuario (usando una segmentación, por ejemplo) y ordenando la tabla creada según el campo <em>Order Date</em>:
Vemos cómo la fecha de última compra coincide con la anterior.
', 'es') (Line: 118)
Drupal\filter\Element\ProcessedText::preRenderText(Array)
call_user_func_array(Array, Array) (Line: 101)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88)
__TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 46)
__TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 43)
__TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110)
__TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, ) (Line: 242)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
- Deprecated function: Creation of dynamic property Drupal\mysql\Driver\Database\mysql\Select::$alterMetaData is deprecated in Drupal\Core\Database\Query\Select->addMetaData() (line 178 of core/lib/Drupal/Core/Database/Query/Select.php).
Drupal\Core\Database\Query\Select->addMetaData('entity_type', 'file') (Line: 115)
Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80)
Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640)
Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63)
Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', '5026e66a-ec6a-46ba-b942-408f7acdaa96') (Line: 95)
Drupal\editor\Plugin\Filter\EditorFileReference->process('Partimos de una tabla de ventas ("<em>Movements</em>") en la que figura la fecha de venta, el identificador del usuario y el importe de venta:
Nuestro objetivo es añadir una nueva columna en la que se muestre la última compra del mismo cliente. Al recorrerse la tabla creándose el nuevo campo se creará para cada fila el contexto de fila asociado, lo que nos da acceso a los campos de la fila. Concretamente, la función <a href="/dax/function/earlier">EARLIER</a> nos permite acceder al identificador del cliente y a la fecha, de forma que podemos calcular el subconjunto de la tabla que contiene las compras del cliente actual anteriores a la fecha actual con la siguiente expresión:
FILTER(
Movements;
Movements[Customer Id] = EARLIER(Movements[Customer Id]) &&
Movements[Order Date] < EARLIER(Movements[Order Date])
)
Una vez calculado este subconjunto, podemos extraer la última fecha muy fácilmente usando la función <a href="/dax/function/lastdate">LASTDATE</a>, función que devuelve una tabla con la última fecha del contexto actual. Usada como argumento de <a href="/dax/function/calculate">CALCULATE</a> y añadiendo como filtro el subconjunto calculado, podemos extraer la última fecha del conjunto (es decir, la última fecha de compra antes de la actual):
Last Purchase =
CALCULATE(
LASTDATE(Movements[Order Date]);
FILTER(
Movements;
Movements[Customer Id] = EARLIER(Movements[Customer Id]) &&
Movements[Order Date] < EARLIER(Movements[Order Date])
)
)
Recordemos que, aunque la función LASTDATE devuelve una tabla, el resultado puede ser usado como un escalar allí donde se requiera una simple fecha. El resultado obtenido es el siguiente:
Podemos confirmar que el cálculo es correcto si llevamos a una visualización tipo tabla el identificador de usuario, el campo <em>Order Date</em> y el campo recién creado <em>Last Purchase</em>, filtrando el identificador de usuario (usando una segmentación, por ejemplo) y ordenando la tabla creada según el campo <em>Order Date</em>:
Vemos cómo la fecha de última compra coincide con la anterior.
', 'es') (Line: 118)
Drupal\filter\Element\ProcessedText::preRenderText(Array)
call_user_func_array(Array, Array) (Line: 101)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88)
__TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 46)
__TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 43)
__TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110)
__TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, ) (Line: 242)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
- Deprecated function: Creation of dynamic property Drupal\mysql\Driver\Database\mysql\Select::$alterTags is deprecated in Drupal\Core\Database\Query\Select->addTag() (line 149 of core/lib/Drupal/Core/Database/Query/Select.php).
Drupal\Core\Database\Query\Select->addTag('entity_query') (Line: 147)
Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80)
Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640)
Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63)
Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', '5026e66a-ec6a-46ba-b942-408f7acdaa96') (Line: 95)
Drupal\editor\Plugin\Filter\EditorFileReference->process('Partimos de una tabla de ventas ("<em>Movements</em>") en la que figura la fecha de venta, el identificador del usuario y el importe de venta:
Nuestro objetivo es añadir una nueva columna en la que se muestre la última compra del mismo cliente. Al recorrerse la tabla creándose el nuevo campo se creará para cada fila el contexto de fila asociado, lo que nos da acceso a los campos de la fila. Concretamente, la función <a href="/dax/function/earlier">EARLIER</a> nos permite acceder al identificador del cliente y a la fecha, de forma que podemos calcular el subconjunto de la tabla que contiene las compras del cliente actual anteriores a la fecha actual con la siguiente expresión:
FILTER(
Movements;
Movements[Customer Id] = EARLIER(Movements[Customer Id]) &&
Movements[Order Date] < EARLIER(Movements[Order Date])
)
Una vez calculado este subconjunto, podemos extraer la última fecha muy fácilmente usando la función <a href="/dax/function/lastdate">LASTDATE</a>, función que devuelve una tabla con la última fecha del contexto actual. Usada como argumento de <a href="/dax/function/calculate">CALCULATE</a> y añadiendo como filtro el subconjunto calculado, podemos extraer la última fecha del conjunto (es decir, la última fecha de compra antes de la actual):
Last Purchase =
CALCULATE(
LASTDATE(Movements[Order Date]);
FILTER(
Movements;
Movements[Customer Id] = EARLIER(Movements[Customer Id]) &&
Movements[Order Date] < EARLIER(Movements[Order Date])
)
)
Recordemos que, aunque la función LASTDATE devuelve una tabla, el resultado puede ser usado como un escalar allí donde se requiera una simple fecha. El resultado obtenido es el siguiente:
Podemos confirmar que el cálculo es correcto si llevamos a una visualización tipo tabla el identificador de usuario, el campo <em>Order Date</em> y el campo recién creado <em>Last Purchase</em>, filtrando el identificador de usuario (usando una segmentación, por ejemplo) y ordenando la tabla creada según el campo <em>Order Date</em>:
Vemos cómo la fecha de última compra coincide con la anterior.
', 'es') (Line: 118)
Drupal\filter\Element\ProcessedText::preRenderText(Array)
call_user_func_array(Array, Array) (Line: 101)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88)
__TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 46)
__TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 43)
__TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110)
__TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, ) (Line: 242)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
- Deprecated function: Creation of dynamic property Drupal\mysql\Driver\Database\mysql\Select::$alterMetaData is deprecated in Drupal\Core\Database\Query\Select->addMetaData() (line 178 of core/lib/Drupal/Core/Database/Query/Select.php).
Drupal\Core\Database\Query\Select->addMetaData('entity_type', 'file') (Line: 115)
Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80)
Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640)
Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63)
Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', '5026e66a-ec6a-46ba-b942-408f7acdaa96') (Line: 124)
Drupal\editor\Plugin\Filter\EditorFileReference->process('Partimos de una tabla de ventas ("<em>Movements</em>") en la que figura la fecha de venta, el identificador del usuario y el importe de venta:
Nuestro objetivo es añadir una nueva columna en la que se muestre la última compra del mismo cliente. Al recorrerse la tabla creándose el nuevo campo se creará para cada fila el contexto de fila asociado, lo que nos da acceso a los campos de la fila. Concretamente, la función <a href="/dax/function/earlier">EARLIER</a> nos permite acceder al identificador del cliente y a la fecha, de forma que podemos calcular el subconjunto de la tabla que contiene las compras del cliente actual anteriores a la fecha actual con la siguiente expresión:
FILTER(
Movements;
Movements[Customer Id] = EARLIER(Movements[Customer Id]) &&
Movements[Order Date] < EARLIER(Movements[Order Date])
)
Una vez calculado este subconjunto, podemos extraer la última fecha muy fácilmente usando la función <a href="/dax/function/lastdate">LASTDATE</a>, función que devuelve una tabla con la última fecha del contexto actual. Usada como argumento de <a href="/dax/function/calculate">CALCULATE</a> y añadiendo como filtro el subconjunto calculado, podemos extraer la última fecha del conjunto (es decir, la última fecha de compra antes de la actual):
Last Purchase =
CALCULATE(
LASTDATE(Movements[Order Date]);
FILTER(
Movements;
Movements[Customer Id] = EARLIER(Movements[Customer Id]) &&
Movements[Order Date] < EARLIER(Movements[Order Date])
)
)
Recordemos que, aunque la función LASTDATE devuelve una tabla, el resultado puede ser usado como un escalar allí donde se requiera una simple fecha. El resultado obtenido es el siguiente:
Podemos confirmar que el cálculo es correcto si llevamos a una visualización tipo tabla el identificador de usuario, el campo <em>Order Date</em> y el campo recién creado <em>Last Purchase</em>, filtrando el identificador de usuario (usando una segmentación, por ejemplo) y ordenando la tabla creada según el campo <em>Order Date</em>:
Vemos cómo la fecha de última compra coincide con la anterior.
', 'es') (Line: 118)
Drupal\filter\Element\ProcessedText::preRenderText(Array)
call_user_func_array(Array, Array) (Line: 101)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88)
__TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 46)
__TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 43)
__TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110)
__TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, ) (Line: 242)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
- Deprecated function: Creation of dynamic property Drupal\mysql\Driver\Database\mysql\Select::$alterTags is deprecated in Drupal\Core\Database\Query\Select->addTag() (line 149 of core/lib/Drupal/Core/Database/Query/Select.php).
Drupal\Core\Database\Query\Select->addTag('entity_query') (Line: 147)
Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80)
Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640)
Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63)
Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', '5026e66a-ec6a-46ba-b942-408f7acdaa96') (Line: 124)
Drupal\editor\Plugin\Filter\EditorFileReference->process('Partimos de una tabla de ventas ("<em>Movements</em>") en la que figura la fecha de venta, el identificador del usuario y el importe de venta:
Nuestro objetivo es añadir una nueva columna en la que se muestre la última compra del mismo cliente. Al recorrerse la tabla creándose el nuevo campo se creará para cada fila el contexto de fila asociado, lo que nos da acceso a los campos de la fila. Concretamente, la función <a href="/dax/function/earlier">EARLIER</a> nos permite acceder al identificador del cliente y a la fecha, de forma que podemos calcular el subconjunto de la tabla que contiene las compras del cliente actual anteriores a la fecha actual con la siguiente expresión:
FILTER(
Movements;
Movements[Customer Id] = EARLIER(Movements[Customer Id]) &&
Movements[Order Date] < EARLIER(Movements[Order Date])
)
Una vez calculado este subconjunto, podemos extraer la última fecha muy fácilmente usando la función <a href="/dax/function/lastdate">LASTDATE</a>, función que devuelve una tabla con la última fecha del contexto actual. Usada como argumento de <a href="/dax/function/calculate">CALCULATE</a> y añadiendo como filtro el subconjunto calculado, podemos extraer la última fecha del conjunto (es decir, la última fecha de compra antes de la actual):
Last Purchase =
CALCULATE(
LASTDATE(Movements[Order Date]);
FILTER(
Movements;
Movements[Customer Id] = EARLIER(Movements[Customer Id]) &&
Movements[Order Date] < EARLIER(Movements[Order Date])
)
)
Recordemos que, aunque la función LASTDATE devuelve una tabla, el resultado puede ser usado como un escalar allí donde se requiera una simple fecha. El resultado obtenido es el siguiente:
Podemos confirmar que el cálculo es correcto si llevamos a una visualización tipo tabla el identificador de usuario, el campo <em>Order Date</em> y el campo recién creado <em>Last Purchase</em>, filtrando el identificador de usuario (usando una segmentación, por ejemplo) y ordenando la tabla creada según el campo <em>Order Date</em>:
Vemos cómo la fecha de última compra coincide con la anterior.
', 'es') (Line: 118)
Drupal\filter\Element\ProcessedText::preRenderText(Array)
call_user_func_array(Array, Array) (Line: 101)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88)
__TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 46)
__TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 43)
__TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110)
__TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, ) (Line: 242)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
- Deprecated function: Creation of dynamic property Drupal\mysql\Driver\Database\mysql\Select::$alterMetaData is deprecated in Drupal\Core\Database\Query\Select->addMetaData() (line 178 of core/lib/Drupal/Core/Database/Query/Select.php).
Drupal\Core\Database\Query\Select->addMetaData('entity_type', 'file') (Line: 115)
Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80)
Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640)
Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63)
Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', 'f6c39c65-644d-4cef-8dc5-6a96e5ea6721') (Line: 95)
Drupal\editor\Plugin\Filter\EditorFileReference->process('Un interesante escenario es aquel que implica una tabla de datos que incluye la "ocupación" de unos ciertos recursos indicando la fecha de comienzo y la de finalización de la ocupación, teniendo como objetivo la visualización de una gráfica en la que se muestre el calendario y los días en los que cada recurso está ocupado o disponible.
Para resolver este escenario partimos de una tabla ("<em>Allocations</em>") en la que se muestra el recurso en cuestión (1, 2 o 3 en nuestro ejemplo), y las fechas de inicio y fin de la ocupación:
Partimos también de un calendario ("<em>Calendar</em>") que, en este ejemplo, está limitado a la quincena dentro de la cual se producen las ocupaciones de cada recurso:
Si generamos un gráfico a mano -usando Excel, por ejemplo-, la visualización de las ocupaciones de cada recurso tendría el siguiente aspecto:
El objetivo es llegar a una visualización semejante que se genere de forma automática.
Obsérvese que si cruzamos la tabla "Allocations" (que incluye los períodos en los que cada recurso está reservado) y el calendario mediante la función <a href="/dax/function/generate">GENERATE</a>, por ejemplo (también valdría la función <a href="/dax/function/crossjoin">CROSSJOIN</a> pues, en este caso, no estamos haciendo uso del contexto de fila generado por las filas de la primera tabla), tendremos todas las posibles combinaciones entre las filas de ambas:
Table =
GENERATE(
Allocations;
'Calendar'
)
Y de esta tabla, es sencillo quedarnos solo con los días en los que el recurso está reservado si seleccionamos apenas aquellas filas en las que el campo <em>Date </em>sea mayor o igual a <em>Start </em>y menor o igual a <em>End</em>, para lo que recurrimos a la función <a href="/dax/function/filter">FILTER</a>:
Table =
FILTER(
GENERATE(
Allocations;
'Calendar'
);
'Calendar'[Date] >= Allocations[Start] && 'Calendar'[Date] <= Allocations[End]
)
En este punto podríamos obviar los campos <em>Start </em>y <em>End</em>, que ya no aportan nada, para lo que podemos recurrir a la función <a href="/dax/function/selectcolumns">SELECTCOLUMNS</a> que nos permite escoger qué campos queremos seleccionar:
Table =
SELECTCOLUMNS(
FILTER(
GENERATE(
Allocations;
'Calendar'
);
'Calendar'[Date] >= Allocations[Start] && 'Calendar'[Date] <= Allocations[End]
);
"Id"; Allocations[Id];
"Resource"; Allocations[Resource];
"Date"; 'Calendar'[Date]
)
Para visualizar el resultado vamos a recurrir a la visualización "<em>as Timeline</em>" descargable desde el marketplace. Una vez llevada al lienzo su configuración es la siguiente:
Y la visualización queda de la siguiente forma:
Podemos comparar el resultado con el esquema realizado a mano:
También habríamos podido aprovechar el contexto de fila creado por la función GENERATE para incluir el filtro dentro de la propia función, de la siguiente manera:
Table =
SELECTCOLUMNS(
GENERATE(
Allocations;
FILTER(
'Calendar';
'Calendar'[Date] >= Allocations[Start] && 'Calendar'[Date] <= Allocations[End]
)
);
"Id"; Allocations[Id];
"Resource"; Allocations[Resource];
"Date"; 'Calendar'[Date]
)
', 'es') (Line: 118)
Drupal\filter\Element\ProcessedText::preRenderText(Array)
call_user_func_array(Array, Array) (Line: 101)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88)
__TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 46)
__TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 43)
__TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110)
__TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, ) (Line: 242)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
- Deprecated function: Creation of dynamic property Drupal\mysql\Driver\Database\mysql\Select::$alterTags is deprecated in Drupal\Core\Database\Query\Select->addTag() (line 149 of core/lib/Drupal/Core/Database/Query/Select.php).
Drupal\Core\Database\Query\Select->addTag('entity_query') (Line: 147)
Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80)
Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640)
Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63)
Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', 'f6c39c65-644d-4cef-8dc5-6a96e5ea6721') (Line: 95)
Drupal\editor\Plugin\Filter\EditorFileReference->process('Un interesante escenario es aquel que implica una tabla de datos que incluye la "ocupación" de unos ciertos recursos indicando la fecha de comienzo y la de finalización de la ocupación, teniendo como objetivo la visualización de una gráfica en la que se muestre el calendario y los días en los que cada recurso está ocupado o disponible.
Para resolver este escenario partimos de una tabla ("<em>Allocations</em>") en la que se muestra el recurso en cuestión (1, 2 o 3 en nuestro ejemplo), y las fechas de inicio y fin de la ocupación:
Partimos también de un calendario ("<em>Calendar</em>") que, en este ejemplo, está limitado a la quincena dentro de la cual se producen las ocupaciones de cada recurso:
Si generamos un gráfico a mano -usando Excel, por ejemplo-, la visualización de las ocupaciones de cada recurso tendría el siguiente aspecto:
El objetivo es llegar a una visualización semejante que se genere de forma automática.
Obsérvese que si cruzamos la tabla "Allocations" (que incluye los períodos en los que cada recurso está reservado) y el calendario mediante la función <a href="/dax/function/generate">GENERATE</a>, por ejemplo (también valdría la función <a href="/dax/function/crossjoin">CROSSJOIN</a> pues, en este caso, no estamos haciendo uso del contexto de fila generado por las filas de la primera tabla), tendremos todas las posibles combinaciones entre las filas de ambas:
Table =
GENERATE(
Allocations;
'Calendar'
)
Y de esta tabla, es sencillo quedarnos solo con los días en los que el recurso está reservado si seleccionamos apenas aquellas filas en las que el campo <em>Date </em>sea mayor o igual a <em>Start </em>y menor o igual a <em>End</em>, para lo que recurrimos a la función <a href="/dax/function/filter">FILTER</a>:
Table =
FILTER(
GENERATE(
Allocations;
'Calendar'
);
'Calendar'[Date] >= Allocations[Start] && 'Calendar'[Date] <= Allocations[End]
)
En este punto podríamos obviar los campos <em>Start </em>y <em>End</em>, que ya no aportan nada, para lo que podemos recurrir a la función <a href="/dax/function/selectcolumns">SELECTCOLUMNS</a> que nos permite escoger qué campos queremos seleccionar:
Table =
SELECTCOLUMNS(
FILTER(
GENERATE(
Allocations;
'Calendar'
);
'Calendar'[Date] >= Allocations[Start] && 'Calendar'[Date] <= Allocations[End]
);
"Id"; Allocations[Id];
"Resource"; Allocations[Resource];
"Date"; 'Calendar'[Date]
)
Para visualizar el resultado vamos a recurrir a la visualización "<em>as Timeline</em>" descargable desde el marketplace. Una vez llevada al lienzo su configuración es la siguiente:
Y la visualización queda de la siguiente forma:
Podemos comparar el resultado con el esquema realizado a mano:
También habríamos podido aprovechar el contexto de fila creado por la función GENERATE para incluir el filtro dentro de la propia función, de la siguiente manera:
Table =
SELECTCOLUMNS(
GENERATE(
Allocations;
FILTER(
'Calendar';
'Calendar'[Date] >= Allocations[Start] && 'Calendar'[Date] <= Allocations[End]
)
);
"Id"; Allocations[Id];
"Resource"; Allocations[Resource];
"Date"; 'Calendar'[Date]
)
', 'es') (Line: 118)
Drupal\filter\Element\ProcessedText::preRenderText(Array)
call_user_func_array(Array, Array) (Line: 101)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88)
__TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 46)
__TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 43)
__TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110)
__TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, ) (Line: 242)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
- Deprecated function: Creation of dynamic property Drupal\mysql\Driver\Database\mysql\Select::$alterMetaData is deprecated in Drupal\Core\Database\Query\Select->addMetaData() (line 178 of core/lib/Drupal/Core/Database/Query/Select.php).
Drupal\Core\Database\Query\Select->addMetaData('entity_type', 'file') (Line: 115)
Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80)
Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640)
Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63)
Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', 'f6c39c65-644d-4cef-8dc5-6a96e5ea6721') (Line: 124)
Drupal\editor\Plugin\Filter\EditorFileReference->process('Un interesante escenario es aquel que implica una tabla de datos que incluye la "ocupación" de unos ciertos recursos indicando la fecha de comienzo y la de finalización de la ocupación, teniendo como objetivo la visualización de una gráfica en la que se muestre el calendario y los días en los que cada recurso está ocupado o disponible.
Para resolver este escenario partimos de una tabla ("<em>Allocations</em>") en la que se muestra el recurso en cuestión (1, 2 o 3 en nuestro ejemplo), y las fechas de inicio y fin de la ocupación:
Partimos también de un calendario ("<em>Calendar</em>") que, en este ejemplo, está limitado a la quincena dentro de la cual se producen las ocupaciones de cada recurso:
Si generamos un gráfico a mano -usando Excel, por ejemplo-, la visualización de las ocupaciones de cada recurso tendría el siguiente aspecto:
El objetivo es llegar a una visualización semejante que se genere de forma automática.
Obsérvese que si cruzamos la tabla "Allocations" (que incluye los períodos en los que cada recurso está reservado) y el calendario mediante la función <a href="/dax/function/generate">GENERATE</a>, por ejemplo (también valdría la función <a href="/dax/function/crossjoin">CROSSJOIN</a> pues, en este caso, no estamos haciendo uso del contexto de fila generado por las filas de la primera tabla), tendremos todas las posibles combinaciones entre las filas de ambas:
Table =
GENERATE(
Allocations;
'Calendar'
)
Y de esta tabla, es sencillo quedarnos solo con los días en los que el recurso está reservado si seleccionamos apenas aquellas filas en las que el campo <em>Date </em>sea mayor o igual a <em>Start </em>y menor o igual a <em>End</em>, para lo que recurrimos a la función <a href="/dax/function/filter">FILTER</a>:
Table =
FILTER(
GENERATE(
Allocations;
'Calendar'
);
'Calendar'[Date] >= Allocations[Start] && 'Calendar'[Date] <= Allocations[End]
)
En este punto podríamos obviar los campos <em>Start </em>y <em>End</em>, que ya no aportan nada, para lo que podemos recurrir a la función <a href="/dax/function/selectcolumns">SELECTCOLUMNS</a> que nos permite escoger qué campos queremos seleccionar:
Table =
SELECTCOLUMNS(
FILTER(
GENERATE(
Allocations;
'Calendar'
);
'Calendar'[Date] >= Allocations[Start] && 'Calendar'[Date] <= Allocations[End]
);
"Id"; Allocations[Id];
"Resource"; Allocations[Resource];
"Date"; 'Calendar'[Date]
)
Para visualizar el resultado vamos a recurrir a la visualización "<em>as Timeline</em>" descargable desde el marketplace. Una vez llevada al lienzo su configuración es la siguiente:
Y la visualización queda de la siguiente forma:
Podemos comparar el resultado con el esquema realizado a mano:
También habríamos podido aprovechar el contexto de fila creado por la función GENERATE para incluir el filtro dentro de la propia función, de la siguiente manera:
Table =
SELECTCOLUMNS(
GENERATE(
Allocations;
FILTER(
'Calendar';
'Calendar'[Date] >= Allocations[Start] && 'Calendar'[Date] <= Allocations[End]
)
);
"Id"; Allocations[Id];
"Resource"; Allocations[Resource];
"Date"; 'Calendar'[Date]
)
', 'es') (Line: 118)
Drupal\filter\Element\ProcessedText::preRenderText(Array)
call_user_func_array(Array, Array) (Line: 101)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88)
__TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 46)
__TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 43)
__TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110)
__TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, ) (Line: 242)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
- Deprecated function: Creation of dynamic property Drupal\mysql\Driver\Database\mysql\Select::$alterTags is deprecated in Drupal\Core\Database\Query\Select->addTag() (line 149 of core/lib/Drupal/Core/Database/Query/Select.php).
Drupal\Core\Database\Query\Select->addTag('entity_query') (Line: 147)
Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80)
Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640)
Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63)
Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', 'f6c39c65-644d-4cef-8dc5-6a96e5ea6721') (Line: 124)
Drupal\editor\Plugin\Filter\EditorFileReference->process('Un interesante escenario es aquel que implica una tabla de datos que incluye la "ocupación" de unos ciertos recursos indicando la fecha de comienzo y la de finalización de la ocupación, teniendo como objetivo la visualización de una gráfica en la que se muestre el calendario y los días en los que cada recurso está ocupado o disponible.
Para resolver este escenario partimos de una tabla ("<em>Allocations</em>") en la que se muestra el recurso en cuestión (1, 2 o 3 en nuestro ejemplo), y las fechas de inicio y fin de la ocupación:
Partimos también de un calendario ("<em>Calendar</em>") que, en este ejemplo, está limitado a la quincena dentro de la cual se producen las ocupaciones de cada recurso:
Si generamos un gráfico a mano -usando Excel, por ejemplo-, la visualización de las ocupaciones de cada recurso tendría el siguiente aspecto:
El objetivo es llegar a una visualización semejante que se genere de forma automática.
Obsérvese que si cruzamos la tabla "Allocations" (que incluye los períodos en los que cada recurso está reservado) y el calendario mediante la función <a href="/dax/function/generate">GENERATE</a>, por ejemplo (también valdría la función <a href="/dax/function/crossjoin">CROSSJOIN</a> pues, en este caso, no estamos haciendo uso del contexto de fila generado por las filas de la primera tabla), tendremos todas las posibles combinaciones entre las filas de ambas:
Table =
GENERATE(
Allocations;
'Calendar'
)
Y de esta tabla, es sencillo quedarnos solo con los días en los que el recurso está reservado si seleccionamos apenas aquellas filas en las que el campo <em>Date </em>sea mayor o igual a <em>Start </em>y menor o igual a <em>End</em>, para lo que recurrimos a la función <a href="/dax/function/filter">FILTER</a>:
Table =
FILTER(
GENERATE(
Allocations;
'Calendar'
);
'Calendar'[Date] >= Allocations[Start] && 'Calendar'[Date] <= Allocations[End]
)
En este punto podríamos obviar los campos <em>Start </em>y <em>End</em>, que ya no aportan nada, para lo que podemos recurrir a la función <a href="/dax/function/selectcolumns">SELECTCOLUMNS</a> que nos permite escoger qué campos queremos seleccionar:
Table =
SELECTCOLUMNS(
FILTER(
GENERATE(
Allocations;
'Calendar'
);
'Calendar'[Date] >= Allocations[Start] && 'Calendar'[Date] <= Allocations[End]
);
"Id"; Allocations[Id];
"Resource"; Allocations[Resource];
"Date"; 'Calendar'[Date]
)
Para visualizar el resultado vamos a recurrir a la visualización "<em>as Timeline</em>" descargable desde el marketplace. Una vez llevada al lienzo su configuración es la siguiente:
Y la visualización queda de la siguiente forma:
Podemos comparar el resultado con el esquema realizado a mano:
También habríamos podido aprovechar el contexto de fila creado por la función GENERATE para incluir el filtro dentro de la propia función, de la siguiente manera:
Table =
SELECTCOLUMNS(
GENERATE(
Allocations;
FILTER(
'Calendar';
'Calendar'[Date] >= Allocations[Start] && 'Calendar'[Date] <= Allocations[End]
)
);
"Id"; Allocations[Id];
"Resource"; Allocations[Resource];
"Date"; 'Calendar'[Date]
)
', 'es') (Line: 118)
Drupal\filter\Element\ProcessedText::preRenderText(Array)
call_user_func_array(Array, Array) (Line: 101)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88)
__TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 46)
__TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 43)
__TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110)
__TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, ) (Line: 242)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
- Deprecated function: Creation of dynamic property Drupal\mysql\Driver\Database\mysql\Select::$alterMetaData is deprecated in Drupal\Core\Database\Query\Select->addMetaData() (line 178 of core/lib/Drupal/Core/Database/Query/Select.php).
Drupal\Core\Database\Query\Select->addMetaData('entity_type', 'file') (Line: 115)
Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80)
Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640)
Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63)
Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', '2baa69eb-5b8b-4255-a6f2-de8576f59025') (Line: 95)
Drupal\editor\Plugin\Filter\EditorFileReference->process('Un interesante escenario es aquel que implica una tabla de datos que incluye la "ocupación" de unos ciertos recursos indicando la fecha de comienzo y la de finalización de la ocupación, teniendo como objetivo la visualización de una gráfica en la que se muestre el calendario y los días en los que cada recurso está ocupado o disponible.
Para resolver este escenario partimos de una tabla ("<em>Allocations</em>") en la que se muestra el recurso en cuestión (1, 2 o 3 en nuestro ejemplo), y las fechas de inicio y fin de la ocupación:
Partimos también de un calendario ("<em>Calendar</em>") que, en este ejemplo, está limitado a la quincena dentro de la cual se producen las ocupaciones de cada recurso:
Si generamos un gráfico a mano -usando Excel, por ejemplo-, la visualización de las ocupaciones de cada recurso tendría el siguiente aspecto:
El objetivo es llegar a una visualización semejante que se genere de forma automática.
Obsérvese que si cruzamos la tabla "Allocations" (que incluye los períodos en los que cada recurso está reservado) y el calendario mediante la función <a href="/dax/function/generate">GENERATE</a>, por ejemplo (también valdría la función <a href="/dax/function/crossjoin">CROSSJOIN</a> pues, en este caso, no estamos haciendo uso del contexto de fila generado por las filas de la primera tabla), tendremos todas las posibles combinaciones entre las filas de ambas:
Table =
GENERATE(
Allocations;
'Calendar'
)
Y de esta tabla, es sencillo quedarnos solo con los días en los que el recurso está reservado si seleccionamos apenas aquellas filas en las que el campo <em>Date </em>sea mayor o igual a <em>Start </em>y menor o igual a <em>End</em>, para lo que recurrimos a la función <a href="/dax/function/filter">FILTER</a>:
Table =
FILTER(
GENERATE(
Allocations;
'Calendar'
);
'Calendar'[Date] >= Allocations[Start] && 'Calendar'[Date] <= Allocations[End]
)
En este punto podríamos obviar los campos <em>Start </em>y <em>End</em>, que ya no aportan nada, para lo que podemos recurrir a la función <a href="/dax/function/selectcolumns">SELECTCOLUMNS</a> que nos permite escoger qué campos queremos seleccionar:
Table =
SELECTCOLUMNS(
FILTER(
GENERATE(
Allocations;
'Calendar'
);
'Calendar'[Date] >= Allocations[Start] && 'Calendar'[Date] <= Allocations[End]
);
"Id"; Allocations[Id];
"Resource"; Allocations[Resource];
"Date"; 'Calendar'[Date]
)
Para visualizar el resultado vamos a recurrir a la visualización "<em>as Timeline</em>" descargable desde el marketplace. Una vez llevada al lienzo su configuración es la siguiente:
Y la visualización queda de la siguiente forma:
Podemos comparar el resultado con el esquema realizado a mano:
También habríamos podido aprovechar el contexto de fila creado por la función GENERATE para incluir el filtro dentro de la propia función, de la siguiente manera:
Table =
SELECTCOLUMNS(
GENERATE(
Allocations;
FILTER(
'Calendar';
'Calendar'[Date] >= Allocations[Start] && 'Calendar'[Date] <= Allocations[End]
)
);
"Id"; Allocations[Id];
"Resource"; Allocations[Resource];
"Date"; 'Calendar'[Date]
)
', 'es') (Line: 118)
Drupal\filter\Element\ProcessedText::preRenderText(Array)
call_user_func_array(Array, Array) (Line: 101)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88)
__TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 46)
__TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 43)
__TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110)
__TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, ) (Line: 242)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
- Deprecated function: Creation of dynamic property Drupal\mysql\Driver\Database\mysql\Select::$alterTags is deprecated in Drupal\Core\Database\Query\Select->addTag() (line 149 of core/lib/Drupal/Core/Database/Query/Select.php).
Drupal\Core\Database\Query\Select->addTag('entity_query') (Line: 147)
Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80)
Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640)
Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63)
Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', '2baa69eb-5b8b-4255-a6f2-de8576f59025') (Line: 95)
Drupal\editor\Plugin\Filter\EditorFileReference->process('Un interesante escenario es aquel que implica una tabla de datos que incluye la "ocupación" de unos ciertos recursos indicando la fecha de comienzo y la de finalización de la ocupación, teniendo como objetivo la visualización de una gráfica en la que se muestre el calendario y los días en los que cada recurso está ocupado o disponible.
Para resolver este escenario partimos de una tabla ("<em>Allocations</em>") en la que se muestra el recurso en cuestión (1, 2 o 3 en nuestro ejemplo), y las fechas de inicio y fin de la ocupación:
Partimos también de un calendario ("<em>Calendar</em>") que, en este ejemplo, está limitado a la quincena dentro de la cual se producen las ocupaciones de cada recurso:
Si generamos un gráfico a mano -usando Excel, por ejemplo-, la visualización de las ocupaciones de cada recurso tendría el siguiente aspecto:
El objetivo es llegar a una visualización semejante que se genere de forma automática.
Obsérvese que si cruzamos la tabla "Allocations" (que incluye los períodos en los que cada recurso está reservado) y el calendario mediante la función <a href="/dax/function/generate">GENERATE</a>, por ejemplo (también valdría la función <a href="/dax/function/crossjoin">CROSSJOIN</a> pues, en este caso, no estamos haciendo uso del contexto de fila generado por las filas de la primera tabla), tendremos todas las posibles combinaciones entre las filas de ambas:
Table =
GENERATE(
Allocations;
'Calendar'
)
Y de esta tabla, es sencillo quedarnos solo con los días en los que el recurso está reservado si seleccionamos apenas aquellas filas en las que el campo <em>Date </em>sea mayor o igual a <em>Start </em>y menor o igual a <em>End</em>, para lo que recurrimos a la función <a href="/dax/function/filter">FILTER</a>:
Table =
FILTER(
GENERATE(
Allocations;
'Calendar'
);
'Calendar'[Date] >= Allocations[Start] && 'Calendar'[Date] <= Allocations[End]
)
En este punto podríamos obviar los campos <em>Start </em>y <em>End</em>, que ya no aportan nada, para lo que podemos recurrir a la función <a href="/dax/function/selectcolumns">SELECTCOLUMNS</a> que nos permite escoger qué campos queremos seleccionar:
Table =
SELECTCOLUMNS(
FILTER(
GENERATE(
Allocations;
'Calendar'
);
'Calendar'[Date] >= Allocations[Start] && 'Calendar'[Date] <= Allocations[End]
);
"Id"; Allocations[Id];
"Resource"; Allocations[Resource];
"Date"; 'Calendar'[Date]
)
Para visualizar el resultado vamos a recurrir a la visualización "<em>as Timeline</em>" descargable desde el marketplace. Una vez llevada al lienzo su configuración es la siguiente:
Y la visualización queda de la siguiente forma:
Podemos comparar el resultado con el esquema realizado a mano:
También habríamos podido aprovechar el contexto de fila creado por la función GENERATE para incluir el filtro dentro de la propia función, de la siguiente manera:
Table =
SELECTCOLUMNS(
GENERATE(
Allocations;
FILTER(
'Calendar';
'Calendar'[Date] >= Allocations[Start] && 'Calendar'[Date] <= Allocations[End]
)
);
"Id"; Allocations[Id];
"Resource"; Allocations[Resource];
"Date"; 'Calendar'[Date]
)
', 'es') (Line: 118)
Drupal\filter\Element\ProcessedText::preRenderText(Array)
call_user_func_array(Array, Array) (Line: 101)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88)
__TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 46)
__TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 43)
__TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110)
__TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, ) (Line: 242)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
- Deprecated function: Creation of dynamic property Drupal\mysql\Driver\Database\mysql\Select::$alterMetaData is deprecated in Drupal\Core\Database\Query\Select->addMetaData() (line 178 of core/lib/Drupal/Core/Database/Query/Select.php).
Drupal\Core\Database\Query\Select->addMetaData('entity_type', 'file') (Line: 115)
Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80)
Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640)
Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63)
Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', '2baa69eb-5b8b-4255-a6f2-de8576f59025') (Line: 124)
Drupal\editor\Plugin\Filter\EditorFileReference->process('Un interesante escenario es aquel que implica una tabla de datos que incluye la "ocupación" de unos ciertos recursos indicando la fecha de comienzo y la de finalización de la ocupación, teniendo como objetivo la visualización de una gráfica en la que se muestre el calendario y los días en los que cada recurso está ocupado o disponible.
Para resolver este escenario partimos de una tabla ("<em>Allocations</em>") en la que se muestra el recurso en cuestión (1, 2 o 3 en nuestro ejemplo), y las fechas de inicio y fin de la ocupación:
Partimos también de un calendario ("<em>Calendar</em>") que, en este ejemplo, está limitado a la quincena dentro de la cual se producen las ocupaciones de cada recurso:
Si generamos un gráfico a mano -usando Excel, por ejemplo-, la visualización de las ocupaciones de cada recurso tendría el siguiente aspecto:
El objetivo es llegar a una visualización semejante que se genere de forma automática.
Obsérvese que si cruzamos la tabla "Allocations" (que incluye los períodos en los que cada recurso está reservado) y el calendario mediante la función <a href="/dax/function/generate">GENERATE</a>, por ejemplo (también valdría la función <a href="/dax/function/crossjoin">CROSSJOIN</a> pues, en este caso, no estamos haciendo uso del contexto de fila generado por las filas de la primera tabla), tendremos todas las posibles combinaciones entre las filas de ambas:
Table =
GENERATE(
Allocations;
'Calendar'
)
Y de esta tabla, es sencillo quedarnos solo con los días en los que el recurso está reservado si seleccionamos apenas aquellas filas en las que el campo <em>Date </em>sea mayor o igual a <em>Start </em>y menor o igual a <em>End</em>, para lo que recurrimos a la función <a href="/dax/function/filter">FILTER</a>:
Table =
FILTER(
GENERATE(
Allocations;
'Calendar'
);
'Calendar'[Date] >= Allocations[Start] && 'Calendar'[Date] <= Allocations[End]
)
En este punto podríamos obviar los campos <em>Start </em>y <em>End</em>, que ya no aportan nada, para lo que podemos recurrir a la función <a href="/dax/function/selectcolumns">SELECTCOLUMNS</a> que nos permite escoger qué campos queremos seleccionar:
Table =
SELECTCOLUMNS(
FILTER(
GENERATE(
Allocations;
'Calendar'
);
'Calendar'[Date] >= Allocations[Start] && 'Calendar'[Date] <= Allocations[End]
);
"Id"; Allocations[Id];
"Resource"; Allocations[Resource];
"Date"; 'Calendar'[Date]
)
Para visualizar el resultado vamos a recurrir a la visualización "<em>as Timeline</em>" descargable desde el marketplace. Una vez llevada al lienzo su configuración es la siguiente:
Y la visualización queda de la siguiente forma:
Podemos comparar el resultado con el esquema realizado a mano:
También habríamos podido aprovechar el contexto de fila creado por la función GENERATE para incluir el filtro dentro de la propia función, de la siguiente manera:
Table =
SELECTCOLUMNS(
GENERATE(
Allocations;
FILTER(
'Calendar';
'Calendar'[Date] >= Allocations[Start] && 'Calendar'[Date] <= Allocations[End]
)
);
"Id"; Allocations[Id];
"Resource"; Allocations[Resource];
"Date"; 'Calendar'[Date]
)
', 'es') (Line: 118)
Drupal\filter\Element\ProcessedText::preRenderText(Array)
call_user_func_array(Array, Array) (Line: 101)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88)
__TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 46)
__TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 43)
__TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110)
__TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, ) (Line: 242)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
- Deprecated function: Creation of dynamic property Drupal\mysql\Driver\Database\mysql\Select::$alterTags is deprecated in Drupal\Core\Database\Query\Select->addTag() (line 149 of core/lib/Drupal/Core/Database/Query/Select.php).
Drupal\Core\Database\Query\Select->addTag('entity_query') (Line: 147)
Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80)
Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640)
Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63)
Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', '2baa69eb-5b8b-4255-a6f2-de8576f59025') (Line: 124)
Drupal\editor\Plugin\Filter\EditorFileReference->process('Un interesante escenario es aquel que implica una tabla de datos que incluye la "ocupación" de unos ciertos recursos indicando la fecha de comienzo y la de finalización de la ocupación, teniendo como objetivo la visualización de una gráfica en la que se muestre el calendario y los días en los que cada recurso está ocupado o disponible.
Para resolver este escenario partimos de una tabla ("<em>Allocations</em>") en la que se muestra el recurso en cuestión (1, 2 o 3 en nuestro ejemplo), y las fechas de inicio y fin de la ocupación:
Partimos también de un calendario ("<em>Calendar</em>") que, en este ejemplo, está limitado a la quincena dentro de la cual se producen las ocupaciones de cada recurso:
Si generamos un gráfico a mano -usando Excel, por ejemplo-, la visualización de las ocupaciones de cada recurso tendría el siguiente aspecto:
El objetivo es llegar a una visualización semejante que se genere de forma automática.
Obsérvese que si cruzamos la tabla "Allocations" (que incluye los períodos en los que cada recurso está reservado) y el calendario mediante la función <a href="/dax/function/generate">GENERATE</a>, por ejemplo (también valdría la función <a href="/dax/function/crossjoin">CROSSJOIN</a> pues, en este caso, no estamos haciendo uso del contexto de fila generado por las filas de la primera tabla), tendremos todas las posibles combinaciones entre las filas de ambas:
Table =
GENERATE(
Allocations;
'Calendar'
)
Y de esta tabla, es sencillo quedarnos solo con los días en los que el recurso está reservado si seleccionamos apenas aquellas filas en las que el campo <em>Date </em>sea mayor o igual a <em>Start </em>y menor o igual a <em>End</em>, para lo que recurrimos a la función <a href="/dax/function/filter">FILTER</a>:
Table =
FILTER(
GENERATE(
Allocations;
'Calendar'
);
'Calendar'[Date] >= Allocations[Start] && 'Calendar'[Date] <= Allocations[End]
)
En este punto podríamos obviar los campos <em>Start </em>y <em>End</em>, que ya no aportan nada, para lo que podemos recurrir a la función <a href="/dax/function/selectcolumns">SELECTCOLUMNS</a> que nos permite escoger qué campos queremos seleccionar:
Table =
SELECTCOLUMNS(
FILTER(
GENERATE(
Allocations;
'Calendar'
);
'Calendar'[Date] >= Allocations[Start] && 'Calendar'[Date] <= Allocations[End]
);
"Id"; Allocations[Id];
"Resource"; Allocations[Resource];
"Date"; 'Calendar'[Date]
)
Para visualizar el resultado vamos a recurrir a la visualización "<em>as Timeline</em>" descargable desde el marketplace. Una vez llevada al lienzo su configuración es la siguiente:
Y la visualización queda de la siguiente forma:
Podemos comparar el resultado con el esquema realizado a mano:
También habríamos podido aprovechar el contexto de fila creado por la función GENERATE para incluir el filtro dentro de la propia función, de la siguiente manera:
Table =
SELECTCOLUMNS(
GENERATE(
Allocations;
FILTER(
'Calendar';
'Calendar'[Date] >= Allocations[Start] && 'Calendar'[Date] <= Allocations[End]
)
);
"Id"; Allocations[Id];
"Resource"; Allocations[Resource];
"Date"; 'Calendar'[Date]
)
', 'es') (Line: 118)
Drupal\filter\Element\ProcessedText::preRenderText(Array)
call_user_func_array(Array, Array) (Line: 101)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88)
__TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 46)
__TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 43)
__TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110)
__TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, ) (Line: 242)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
- Deprecated function: Creation of dynamic property Drupal\mysql\Driver\Database\mysql\Select::$alterMetaData is deprecated in Drupal\Core\Database\Query\Select->addMetaData() (line 178 of core/lib/Drupal/Core/Database/Query/Select.php).
Drupal\Core\Database\Query\Select->addMetaData('entity_type', 'file') (Line: 115)
Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80)
Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640)
Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63)
Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', 'e9a0d18c-4220-4395-972b-4e8c163c297f') (Line: 95)
Drupal\editor\Plugin\Filter\EditorFileReference->process('Un interesante escenario es aquel que implica una tabla de datos que incluye la "ocupación" de unos ciertos recursos indicando la fecha de comienzo y la de finalización de la ocupación, teniendo como objetivo la visualización de una gráfica en la que se muestre el calendario y los días en los que cada recurso está ocupado o disponible.
Para resolver este escenario partimos de una tabla ("<em>Allocations</em>") en la que se muestra el recurso en cuestión (1, 2 o 3 en nuestro ejemplo), y las fechas de inicio y fin de la ocupación:
Partimos también de un calendario ("<em>Calendar</em>") que, en este ejemplo, está limitado a la quincena dentro de la cual se producen las ocupaciones de cada recurso:
Si generamos un gráfico a mano -usando Excel, por ejemplo-, la visualización de las ocupaciones de cada recurso tendría el siguiente aspecto:
El objetivo es llegar a una visualización semejante que se genere de forma automática.
Obsérvese que si cruzamos la tabla "Allocations" (que incluye los períodos en los que cada recurso está reservado) y el calendario mediante la función <a href="/dax/function/generate">GENERATE</a>, por ejemplo (también valdría la función <a href="/dax/function/crossjoin">CROSSJOIN</a> pues, en este caso, no estamos haciendo uso del contexto de fila generado por las filas de la primera tabla), tendremos todas las posibles combinaciones entre las filas de ambas:
Table =
GENERATE(
Allocations;
'Calendar'
)
Y de esta tabla, es sencillo quedarnos solo con los días en los que el recurso está reservado si seleccionamos apenas aquellas filas en las que el campo <em>Date </em>sea mayor o igual a <em>Start </em>y menor o igual a <em>End</em>, para lo que recurrimos a la función <a href="/dax/function/filter">FILTER</a>:
Table =
FILTER(
GENERATE(
Allocations;
'Calendar'
);
'Calendar'[Date] >= Allocations[Start] && 'Calendar'[Date] <= Allocations[End]
)
En este punto podríamos obviar los campos <em>Start </em>y <em>End</em>, que ya no aportan nada, para lo que podemos recurrir a la función <a href="/dax/function/selectcolumns">SELECTCOLUMNS</a> que nos permite escoger qué campos queremos seleccionar:
Table =
SELECTCOLUMNS(
FILTER(
GENERATE(
Allocations;
'Calendar'
);
'Calendar'[Date] >= Allocations[Start] && 'Calendar'[Date] <= Allocations[End]
);
"Id"; Allocations[Id];
"Resource"; Allocations[Resource];
"Date"; 'Calendar'[Date]
)
Para visualizar el resultado vamos a recurrir a la visualización "<em>as Timeline</em>" descargable desde el marketplace. Una vez llevada al lienzo su configuración es la siguiente:
Y la visualización queda de la siguiente forma:
Podemos comparar el resultado con el esquema realizado a mano:
También habríamos podido aprovechar el contexto de fila creado por la función GENERATE para incluir el filtro dentro de la propia función, de la siguiente manera:
Table =
SELECTCOLUMNS(
GENERATE(
Allocations;
FILTER(
'Calendar';
'Calendar'[Date] >= Allocations[Start] && 'Calendar'[Date] <= Allocations[End]
)
);
"Id"; Allocations[Id];
"Resource"; Allocations[Resource];
"Date"; 'Calendar'[Date]
)
', 'es') (Line: 118)
Drupal\filter\Element\ProcessedText::preRenderText(Array)
call_user_func_array(Array, Array) (Line: 101)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88)
__TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 46)
__TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 43)
__TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110)
__TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, ) (Line: 242)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
- Deprecated function: Creation of dynamic property Drupal\mysql\Driver\Database\mysql\Select::$alterTags is deprecated in Drupal\Core\Database\Query\Select->addTag() (line 149 of core/lib/Drupal/Core/Database/Query/Select.php).
Drupal\Core\Database\Query\Select->addTag('entity_query') (Line: 147)
Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80)
Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640)
Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63)
Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', 'e9a0d18c-4220-4395-972b-4e8c163c297f') (Line: 95)
Drupal\editor\Plugin\Filter\EditorFileReference->process('Un interesante escenario es aquel que implica una tabla de datos que incluye la "ocupación" de unos ciertos recursos indicando la fecha de comienzo y la de finalización de la ocupación, teniendo como objetivo la visualización de una gráfica en la que se muestre el calendario y los días en los que cada recurso está ocupado o disponible.
Para resolver este escenario partimos de una tabla ("<em>Allocations</em>") en la que se muestra el recurso en cuestión (1, 2 o 3 en nuestro ejemplo), y las fechas de inicio y fin de la ocupación:
Partimos también de un calendario ("<em>Calendar</em>") que, en este ejemplo, está limitado a la quincena dentro de la cual se producen las ocupaciones de cada recurso:
Si generamos un gráfico a mano -usando Excel, por ejemplo-, la visualización de las ocupaciones de cada recurso tendría el siguiente aspecto:
El objetivo es llegar a una visualización semejante que se genere de forma automática.
Obsérvese que si cruzamos la tabla "Allocations" (que incluye los períodos en los que cada recurso está reservado) y el calendario mediante la función <a href="/dax/function/generate">GENERATE</a>, por ejemplo (también valdría la función <a href="/dax/function/crossjoin">CROSSJOIN</a> pues, en este caso, no estamos haciendo uso del contexto de fila generado por las filas de la primera tabla), tendremos todas las posibles combinaciones entre las filas de ambas:
Table =
GENERATE(
Allocations;
'Calendar'
)
Y de esta tabla, es sencillo quedarnos solo con los días en los que el recurso está reservado si seleccionamos apenas aquellas filas en las que el campo <em>Date </em>sea mayor o igual a <em>Start </em>y menor o igual a <em>End</em>, para lo que recurrimos a la función <a href="/dax/function/filter">FILTER</a>:
Table =
FILTER(
GENERATE(
Allocations;
'Calendar'
);
'Calendar'[Date] >= Allocations[Start] && 'Calendar'[Date] <= Allocations[End]
)
En este punto podríamos obviar los campos <em>Start </em>y <em>End</em>, que ya no aportan nada, para lo que podemos recurrir a la función <a href="/dax/function/selectcolumns">SELECTCOLUMNS</a> que nos permite escoger qué campos queremos seleccionar:
Table =
SELECTCOLUMNS(
FILTER(
GENERATE(
Allocations;
'Calendar'
);
'Calendar'[Date] >= Allocations[Start] && 'Calendar'[Date] <= Allocations[End]
);
"Id"; Allocations[Id];
"Resource"; Allocations[Resource];
"Date"; 'Calendar'[Date]
)
Para visualizar el resultado vamos a recurrir a la visualización "<em>as Timeline</em>" descargable desde el marketplace. Una vez llevada al lienzo su configuración es la siguiente:
Y la visualización queda de la siguiente forma:
Podemos comparar el resultado con el esquema realizado a mano:
También habríamos podido aprovechar el contexto de fila creado por la función GENERATE para incluir el filtro dentro de la propia función, de la siguiente manera:
Table =
SELECTCOLUMNS(
GENERATE(
Allocations;
FILTER(
'Calendar';
'Calendar'[Date] >= Allocations[Start] && 'Calendar'[Date] <= Allocations[End]
)
);
"Id"; Allocations[Id];
"Resource"; Allocations[Resource];
"Date"; 'Calendar'[Date]
)
', 'es') (Line: 118)
Drupal\filter\Element\ProcessedText::preRenderText(Array)
call_user_func_array(Array, Array) (Line: 101)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88)
__TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 46)
__TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 43)
__TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110)
__TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, ) (Line: 242)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
- Deprecated function: Creation of dynamic property Drupal\mysql\Driver\Database\mysql\Select::$alterMetaData is deprecated in Drupal\Core\Database\Query\Select->addMetaData() (line 178 of core/lib/Drupal/Core/Database/Query/Select.php).
Drupal\Core\Database\Query\Select->addMetaData('entity_type', 'file') (Line: 115)
Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80)
Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640)
Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63)
Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', 'e9a0d18c-4220-4395-972b-4e8c163c297f') (Line: 124)
Drupal\editor\Plugin\Filter\EditorFileReference->process('Un interesante escenario es aquel que implica una tabla de datos que incluye la "ocupación" de unos ciertos recursos indicando la fecha de comienzo y la de finalización de la ocupación, teniendo como objetivo la visualización de una gráfica en la que se muestre el calendario y los días en los que cada recurso está ocupado o disponible.
Para resolver este escenario partimos de una tabla ("<em>Allocations</em>") en la que se muestra el recurso en cuestión (1, 2 o 3 en nuestro ejemplo), y las fechas de inicio y fin de la ocupación:
Partimos también de un calendario ("<em>Calendar</em>") que, en este ejemplo, está limitado a la quincena dentro de la cual se producen las ocupaciones de cada recurso:
Si generamos un gráfico a mano -usando Excel, por ejemplo-, la visualización de las ocupaciones de cada recurso tendría el siguiente aspecto:
El objetivo es llegar a una visualización semejante que se genere de forma automática.
Obsérvese que si cruzamos la tabla "Allocations" (que incluye los períodos en los que cada recurso está reservado) y el calendario mediante la función <a href="/dax/function/generate">GENERATE</a>, por ejemplo (también valdría la función <a href="/dax/function/crossjoin">CROSSJOIN</a> pues, en este caso, no estamos haciendo uso del contexto de fila generado por las filas de la primera tabla), tendremos todas las posibles combinaciones entre las filas de ambas:
Table =
GENERATE(
Allocations;
'Calendar'
)
Y de esta tabla, es sencillo quedarnos solo con los días en los que el recurso está reservado si seleccionamos apenas aquellas filas en las que el campo <em>Date </em>sea mayor o igual a <em>Start </em>y menor o igual a <em>End</em>, para lo que recurrimos a la función <a href="/dax/function/filter">FILTER</a>:
Table =
FILTER(
GENERATE(
Allocations;
'Calendar'
);
'Calendar'[Date] >= Allocations[Start] && 'Calendar'[Date] <= Allocations[End]
)
En este punto podríamos obviar los campos <em>Start </em>y <em>End</em>, que ya no aportan nada, para lo que podemos recurrir a la función <a href="/dax/function/selectcolumns">SELECTCOLUMNS</a> que nos permite escoger qué campos queremos seleccionar:
Table =
SELECTCOLUMNS(
FILTER(
GENERATE(
Allocations;
'Calendar'
);
'Calendar'[Date] >= Allocations[Start] && 'Calendar'[Date] <= Allocations[End]
);
"Id"; Allocations[Id];
"Resource"; Allocations[Resource];
"Date"; 'Calendar'[Date]
)
Para visualizar el resultado vamos a recurrir a la visualización "<em>as Timeline</em>" descargable desde el marketplace. Una vez llevada al lienzo su configuración es la siguiente:
Y la visualización queda de la siguiente forma:
Podemos comparar el resultado con el esquema realizado a mano:
También habríamos podido aprovechar el contexto de fila creado por la función GENERATE para incluir el filtro dentro de la propia función, de la siguiente manera:
Table =
SELECTCOLUMNS(
GENERATE(
Allocations;
FILTER(
'Calendar';
'Calendar'[Date] >= Allocations[Start] && 'Calendar'[Date] <= Allocations[End]
)
);
"Id"; Allocations[Id];
"Resource"; Allocations[Resource];
"Date"; 'Calendar'[Date]
)
', 'es') (Line: 118)
Drupal\filter\Element\ProcessedText::preRenderText(Array)
call_user_func_array(Array, Array) (Line: 101)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88)
__TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 46)
__TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 43)
__TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110)
__TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, ) (Line: 242)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
- Deprecated function: Creation of dynamic property Drupal\mysql\Driver\Database\mysql\Select::$alterTags is deprecated in Drupal\Core\Database\Query\Select->addTag() (line 149 of core/lib/Drupal/Core/Database/Query/Select.php).
Drupal\Core\Database\Query\Select->addTag('entity_query') (Line: 147)
Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80)
Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640)
Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63)
Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', 'e9a0d18c-4220-4395-972b-4e8c163c297f') (Line: 124)
Drupal\editor\Plugin\Filter\EditorFileReference->process('Un interesante escenario es aquel que implica una tabla de datos que incluye la "ocupación" de unos ciertos recursos indicando la fecha de comienzo y la de finalización de la ocupación, teniendo como objetivo la visualización de una gráfica en la que se muestre el calendario y los días en los que cada recurso está ocupado o disponible.
Para resolver este escenario partimos de una tabla ("<em>Allocations</em>") en la que se muestra el recurso en cuestión (1, 2 o 3 en nuestro ejemplo), y las fechas de inicio y fin de la ocupación:
Partimos también de un calendario ("<em>Calendar</em>") que, en este ejemplo, está limitado a la quincena dentro de la cual se producen las ocupaciones de cada recurso:
Si generamos un gráfico a mano -usando Excel, por ejemplo-, la visualización de las ocupaciones de cada recurso tendría el siguiente aspecto:
El objetivo es llegar a una visualización semejante que se genere de forma automática.
Obsérvese que si cruzamos la tabla "Allocations" (que incluye los períodos en los que cada recurso está reservado) y el calendario mediante la función <a href="/dax/function/generate">GENERATE</a>, por ejemplo (también valdría la función <a href="/dax/function/crossjoin">CROSSJOIN</a> pues, en este caso, no estamos haciendo uso del contexto de fila generado por las filas de la primera tabla), tendremos todas las posibles combinaciones entre las filas de ambas:
Table =
GENERATE(
Allocations;
'Calendar'
)
Y de esta tabla, es sencillo quedarnos solo con los días en los que el recurso está reservado si seleccionamos apenas aquellas filas en las que el campo <em>Date </em>sea mayor o igual a <em>Start </em>y menor o igual a <em>End</em>, para lo que recurrimos a la función <a href="/dax/function/filter">FILTER</a>:
Table =
FILTER(
GENERATE(
Allocations;
'Calendar'
);
'Calendar'[Date] >= Allocations[Start] && 'Calendar'[Date] <= Allocations[End]
)
En este punto podríamos obviar los campos <em>Start </em>y <em>End</em>, que ya no aportan nada, para lo que podemos recurrir a la función <a href="/dax/function/selectcolumns">SELECTCOLUMNS</a> que nos permite escoger qué campos queremos seleccionar:
Table =
SELECTCOLUMNS(
FILTER(
GENERATE(
Allocations;
'Calendar'
);
'Calendar'[Date] >= Allocations[Start] && 'Calendar'[Date] <= Allocations[End]
);
"Id"; Allocations[Id];
"Resource"; Allocations[Resource];
"Date"; 'Calendar'[Date]
)
Para visualizar el resultado vamos a recurrir a la visualización "<em>as Timeline</em>" descargable desde el marketplace. Una vez llevada al lienzo su configuración es la siguiente:
Y la visualización queda de la siguiente forma:
Podemos comparar el resultado con el esquema realizado a mano:
También habríamos podido aprovechar el contexto de fila creado por la función GENERATE para incluir el filtro dentro de la propia función, de la siguiente manera:
Table =
SELECTCOLUMNS(
GENERATE(
Allocations;
FILTER(
'Calendar';
'Calendar'[Date] >= Allocations[Start] && 'Calendar'[Date] <= Allocations[End]
)
);
"Id"; Allocations[Id];
"Resource"; Allocations[Resource];
"Date"; 'Calendar'[Date]
)
', 'es') (Line: 118)
Drupal\filter\Element\ProcessedText::preRenderText(Array)
call_user_func_array(Array, Array) (Line: 101)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88)
__TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 46)
__TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 43)
__TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110)
__TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, ) (Line: 242)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
- Deprecated function: Creation of dynamic property Drupal\mysql\Driver\Database\mysql\Select::$alterMetaData is deprecated in Drupal\Core\Database\Query\Select->addMetaData() (line 178 of core/lib/Drupal/Core/Database/Query/Select.php).
Drupal\Core\Database\Query\Select->addMetaData('entity_type', 'file') (Line: 115)
Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80)
Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640)
Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63)
Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', '8f7e8fc7-4298-448b-8f94-01932657e909') (Line: 95)
Drupal\editor\Plugin\Filter\EditorFileReference->process('Un interesante escenario es aquel que implica una tabla de datos que incluye la "ocupación" de unos ciertos recursos indicando la fecha de comienzo y la de finalización de la ocupación, teniendo como objetivo la visualización de una gráfica en la que se muestre el calendario y los días en los que cada recurso está ocupado o disponible.
Para resolver este escenario partimos de una tabla ("<em>Allocations</em>") en la que se muestra el recurso en cuestión (1, 2 o 3 en nuestro ejemplo), y las fechas de inicio y fin de la ocupación:
Partimos también de un calendario ("<em>Calendar</em>") que, en este ejemplo, está limitado a la quincena dentro de la cual se producen las ocupaciones de cada recurso:
Si generamos un gráfico a mano -usando Excel, por ejemplo-, la visualización de las ocupaciones de cada recurso tendría el siguiente aspecto:
El objetivo es llegar a una visualización semejante que se genere de forma automática.
Obsérvese que si cruzamos la tabla "Allocations" (que incluye los períodos en los que cada recurso está reservado) y el calendario mediante la función <a href="/dax/function/generate">GENERATE</a>, por ejemplo (también valdría la función <a href="/dax/function/crossjoin">CROSSJOIN</a> pues, en este caso, no estamos haciendo uso del contexto de fila generado por las filas de la primera tabla), tendremos todas las posibles combinaciones entre las filas de ambas:
Table =
GENERATE(
Allocations;
'Calendar'
)
Y de esta tabla, es sencillo quedarnos solo con los días en los que el recurso está reservado si seleccionamos apenas aquellas filas en las que el campo <em>Date </em>sea mayor o igual a <em>Start </em>y menor o igual a <em>End</em>, para lo que recurrimos a la función <a href="/dax/function/filter">FILTER</a>:
Table =
FILTER(
GENERATE(
Allocations;
'Calendar'
);
'Calendar'[Date] >= Allocations[Start] && 'Calendar'[Date] <= Allocations[End]
)
En este punto podríamos obviar los campos <em>Start </em>y <em>End</em>, que ya no aportan nada, para lo que podemos recurrir a la función <a href="/dax/function/selectcolumns">SELECTCOLUMNS</a> que nos permite escoger qué campos queremos seleccionar:
Table =
SELECTCOLUMNS(
FILTER(
GENERATE(
Allocations;
'Calendar'
);
'Calendar'[Date] >= Allocations[Start] && 'Calendar'[Date] <= Allocations[End]
);
"Id"; Allocations[Id];
"Resource"; Allocations[Resource];
"Date"; 'Calendar'[Date]
)
Para visualizar el resultado vamos a recurrir a la visualización "<em>as Timeline</em>" descargable desde el marketplace. Una vez llevada al lienzo su configuración es la siguiente:
Y la visualización queda de la siguiente forma:
Podemos comparar el resultado con el esquema realizado a mano:
También habríamos podido aprovechar el contexto de fila creado por la función GENERATE para incluir el filtro dentro de la propia función, de la siguiente manera:
Table =
SELECTCOLUMNS(
GENERATE(
Allocations;
FILTER(
'Calendar';
'Calendar'[Date] >= Allocations[Start] && 'Calendar'[Date] <= Allocations[End]
)
);
"Id"; Allocations[Id];
"Resource"; Allocations[Resource];
"Date"; 'Calendar'[Date]
)
', 'es') (Line: 118)
Drupal\filter\Element\ProcessedText::preRenderText(Array)
call_user_func_array(Array, Array) (Line: 101)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88)
__TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 46)
__TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 43)
__TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110)
__TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, ) (Line: 242)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
- Deprecated function: Creation of dynamic property Drupal\mysql\Driver\Database\mysql\Select::$alterTags is deprecated in Drupal\Core\Database\Query\Select->addTag() (line 149 of core/lib/Drupal/Core/Database/Query/Select.php).
Drupal\Core\Database\Query\Select->addTag('entity_query') (Line: 147)
Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80)
Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640)
Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63)
Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', '8f7e8fc7-4298-448b-8f94-01932657e909') (Line: 95)
Drupal\editor\Plugin\Filter\EditorFileReference->process('Un interesante escenario es aquel que implica una tabla de datos que incluye la "ocupación" de unos ciertos recursos indicando la fecha de comienzo y la de finalización de la ocupación, teniendo como objetivo la visualización de una gráfica en la que se muestre el calendario y los días en los que cada recurso está ocupado o disponible.
Para resolver este escenario partimos de una tabla ("<em>Allocations</em>") en la que se muestra el recurso en cuestión (1, 2 o 3 en nuestro ejemplo), y las fechas de inicio y fin de la ocupación:
Partimos también de un calendario ("<em>Calendar</em>") que, en este ejemplo, está limitado a la quincena dentro de la cual se producen las ocupaciones de cada recurso:
Si generamos un gráfico a mano -usando Excel, por ejemplo-, la visualización de las ocupaciones de cada recurso tendría el siguiente aspecto:
El objetivo es llegar a una visualización semejante que se genere de forma automática.
Obsérvese que si cruzamos la tabla "Allocations" (que incluye los períodos en los que cada recurso está reservado) y el calendario mediante la función <a href="/dax/function/generate">GENERATE</a>, por ejemplo (también valdría la función <a href="/dax/function/crossjoin">CROSSJOIN</a> pues, en este caso, no estamos haciendo uso del contexto de fila generado por las filas de la primera tabla), tendremos todas las posibles combinaciones entre las filas de ambas:
Table =
GENERATE(
Allocations;
'Calendar'
)
Y de esta tabla, es sencillo quedarnos solo con los días en los que el recurso está reservado si seleccionamos apenas aquellas filas en las que el campo <em>Date </em>sea mayor o igual a <em>Start </em>y menor o igual a <em>End</em>, para lo que recurrimos a la función <a href="/dax/function/filter">FILTER</a>:
Table =
FILTER(
GENERATE(
Allocations;
'Calendar'
);
'Calendar'[Date] >= Allocations[Start] && 'Calendar'[Date] <= Allocations[End]
)
En este punto podríamos obviar los campos <em>Start </em>y <em>End</em>, que ya no aportan nada, para lo que podemos recurrir a la función <a href="/dax/function/selectcolumns">SELECTCOLUMNS</a> que nos permite escoger qué campos queremos seleccionar:
Table =
SELECTCOLUMNS(
FILTER(
GENERATE(
Allocations;
'Calendar'
);
'Calendar'[Date] >= Allocations[Start] && 'Calendar'[Date] <= Allocations[End]
);
"Id"; Allocations[Id];
"Resource"; Allocations[Resource];
"Date"; 'Calendar'[Date]
)
Para visualizar el resultado vamos a recurrir a la visualización "<em>as Timeline</em>" descargable desde el marketplace. Una vez llevada al lienzo su configuración es la siguiente:
Y la visualización queda de la siguiente forma:
Podemos comparar el resultado con el esquema realizado a mano:
También habríamos podido aprovechar el contexto de fila creado por la función GENERATE para incluir el filtro dentro de la propia función, de la siguiente manera:
Table =
SELECTCOLUMNS(
GENERATE(
Allocations;
FILTER(
'Calendar';
'Calendar'[Date] >= Allocations[Start] && 'Calendar'[Date] <= Allocations[End]
)
);
"Id"; Allocations[Id];
"Resource"; Allocations[Resource];
"Date"; 'Calendar'[Date]
)
', 'es') (Line: 118)
Drupal\filter\Element\ProcessedText::preRenderText(Array)
call_user_func_array(Array, Array) (Line: 101)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88)
__TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 46)
__TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 43)
__TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110)
__TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, ) (Line: 242)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
- Deprecated function: Creation of dynamic property Drupal\mysql\Driver\Database\mysql\Select::$alterMetaData is deprecated in Drupal\Core\Database\Query\Select->addMetaData() (line 178 of core/lib/Drupal/Core/Database/Query/Select.php).
Drupal\Core\Database\Query\Select->addMetaData('entity_type', 'file') (Line: 115)
Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80)
Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640)
Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63)
Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', '8f7e8fc7-4298-448b-8f94-01932657e909') (Line: 124)
Drupal\editor\Plugin\Filter\EditorFileReference->process('Un interesante escenario es aquel que implica una tabla de datos que incluye la "ocupación" de unos ciertos recursos indicando la fecha de comienzo y la de finalización de la ocupación, teniendo como objetivo la visualización de una gráfica en la que se muestre el calendario y los días en los que cada recurso está ocupado o disponible.
Para resolver este escenario partimos de una tabla ("<em>Allocations</em>") en la que se muestra el recurso en cuestión (1, 2 o 3 en nuestro ejemplo), y las fechas de inicio y fin de la ocupación:
Partimos también de un calendario ("<em>Calendar</em>") que, en este ejemplo, está limitado a la quincena dentro de la cual se producen las ocupaciones de cada recurso:
Si generamos un gráfico a mano -usando Excel, por ejemplo-, la visualización de las ocupaciones de cada recurso tendría el siguiente aspecto:
El objetivo es llegar a una visualización semejante que se genere de forma automática.
Obsérvese que si cruzamos la tabla "Allocations" (que incluye los períodos en los que cada recurso está reservado) y el calendario mediante la función <a href="/dax/function/generate">GENERATE</a>, por ejemplo (también valdría la función <a href="/dax/function/crossjoin">CROSSJOIN</a> pues, en este caso, no estamos haciendo uso del contexto de fila generado por las filas de la primera tabla), tendremos todas las posibles combinaciones entre las filas de ambas:
Table =
GENERATE(
Allocations;
'Calendar'
)
Y de esta tabla, es sencillo quedarnos solo con los días en los que el recurso está reservado si seleccionamos apenas aquellas filas en las que el campo <em>Date </em>sea mayor o igual a <em>Start </em>y menor o igual a <em>End</em>, para lo que recurrimos a la función <a href="/dax/function/filter">FILTER</a>:
Table =
FILTER(
GENERATE(
Allocations;
'Calendar'
);
'Calendar'[Date] >= Allocations[Start] && 'Calendar'[Date] <= Allocations[End]
)
En este punto podríamos obviar los campos <em>Start </em>y <em>End</em>, que ya no aportan nada, para lo que podemos recurrir a la función <a href="/dax/function/selectcolumns">SELECTCOLUMNS</a> que nos permite escoger qué campos queremos seleccionar:
Table =
SELECTCOLUMNS(
FILTER(
GENERATE(
Allocations;
'Calendar'
);
'Calendar'[Date] >= Allocations[Start] && 'Calendar'[Date] <= Allocations[End]
);
"Id"; Allocations[Id];
"Resource"; Allocations[Resource];
"Date"; 'Calendar'[Date]
)
Para visualizar el resultado vamos a recurrir a la visualización "<em>as Timeline</em>" descargable desde el marketplace. Una vez llevada al lienzo su configuración es la siguiente:
Y la visualización queda de la siguiente forma:
Podemos comparar el resultado con el esquema realizado a mano:
También habríamos podido aprovechar el contexto de fila creado por la función GENERATE para incluir el filtro dentro de la propia función, de la siguiente manera:
Table =
SELECTCOLUMNS(
GENERATE(
Allocations;
FILTER(
'Calendar';
'Calendar'[Date] >= Allocations[Start] && 'Calendar'[Date] <= Allocations[End]
)
);
"Id"; Allocations[Id];
"Resource"; Allocations[Resource];
"Date"; 'Calendar'[Date]
)
', 'es') (Line: 118)
Drupal\filter\Element\ProcessedText::preRenderText(Array)
call_user_func_array(Array, Array) (Line: 101)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88)
__TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 46)
__TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 43)
__TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110)
__TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, ) (Line: 242)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
- Deprecated function: Creation of dynamic property Drupal\mysql\Driver\Database\mysql\Select::$alterTags is deprecated in Drupal\Core\Database\Query\Select->addTag() (line 149 of core/lib/Drupal/Core/Database/Query/Select.php).
Drupal\Core\Database\Query\Select->addTag('entity_query') (Line: 147)
Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80)
Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640)
Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63)
Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', '8f7e8fc7-4298-448b-8f94-01932657e909') (Line: 124)
Drupal\editor\Plugin\Filter\EditorFileReference->process('Un interesante escenario es aquel que implica una tabla de datos que incluye la "ocupación" de unos ciertos recursos indicando la fecha de comienzo y la de finalización de la ocupación, teniendo como objetivo la visualización de una gráfica en la que se muestre el calendario y los días en los que cada recurso está ocupado o disponible.
Para resolver este escenario partimos de una tabla ("<em>Allocations</em>") en la que se muestra el recurso en cuestión (1, 2 o 3 en nuestro ejemplo), y las fechas de inicio y fin de la ocupación:
Partimos también de un calendario ("<em>Calendar</em>") que, en este ejemplo, está limitado a la quincena dentro de la cual se producen las ocupaciones de cada recurso:
Si generamos un gráfico a mano -usando Excel, por ejemplo-, la visualización de las ocupaciones de cada recurso tendría el siguiente aspecto:
El objetivo es llegar a una visualización semejante que se genere de forma automática.
Obsérvese que si cruzamos la tabla "Allocations" (que incluye los períodos en los que cada recurso está reservado) y el calendario mediante la función <a href="/dax/function/generate">GENERATE</a>, por ejemplo (también valdría la función <a href="/dax/function/crossjoin">CROSSJOIN</a> pues, en este caso, no estamos haciendo uso del contexto de fila generado por las filas de la primera tabla), tendremos todas las posibles combinaciones entre las filas de ambas:
Table =
GENERATE(
Allocations;
'Calendar'
)
Y de esta tabla, es sencillo quedarnos solo con los días en los que el recurso está reservado si seleccionamos apenas aquellas filas en las que el campo <em>Date </em>sea mayor o igual a <em>Start </em>y menor o igual a <em>End</em>, para lo que recurrimos a la función <a href="/dax/function/filter">FILTER</a>:
Table =
FILTER(
GENERATE(
Allocations;
'Calendar'
);
'Calendar'[Date] >= Allocations[Start] && 'Calendar'[Date] <= Allocations[End]
)
En este punto podríamos obviar los campos <em>Start </em>y <em>End</em>, que ya no aportan nada, para lo que podemos recurrir a la función <a href="/dax/function/selectcolumns">SELECTCOLUMNS</a> que nos permite escoger qué campos queremos seleccionar:
Table =
SELECTCOLUMNS(
FILTER(
GENERATE(
Allocations;
'Calendar'
);
'Calendar'[Date] >= Allocations[Start] && 'Calendar'[Date] <= Allocations[End]
);
"Id"; Allocations[Id];
"Resource"; Allocations[Resource];
"Date"; 'Calendar'[Date]
)
Para visualizar el resultado vamos a recurrir a la visualización "<em>as Timeline</em>" descargable desde el marketplace. Una vez llevada al lienzo su configuración es la siguiente:
Y la visualización queda de la siguiente forma:
Podemos comparar el resultado con el esquema realizado a mano:
También habríamos podido aprovechar el contexto de fila creado por la función GENERATE para incluir el filtro dentro de la propia función, de la siguiente manera:
Table =
SELECTCOLUMNS(
GENERATE(
Allocations;
FILTER(
'Calendar';
'Calendar'[Date] >= Allocations[Start] && 'Calendar'[Date] <= Allocations[End]
)
);
"Id"; Allocations[Id];
"Resource"; Allocations[Resource];
"Date"; 'Calendar'[Date]
)
', 'es') (Line: 118)
Drupal\filter\Element\ProcessedText::preRenderText(Array)
call_user_func_array(Array, Array) (Line: 101)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88)
__TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 46)
__TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 43)
__TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110)
__TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, ) (Line: 242)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
- Deprecated function: Creation of dynamic property Drupal\mysql\Driver\Database\mysql\Select::$alterMetaData is deprecated in Drupal\Core\Database\Query\Select->addMetaData() (line 178 of core/lib/Drupal/Core/Database/Query/Select.php).
Drupal\Core\Database\Query\Select->addMetaData('entity_type', 'file') (Line: 115)
Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80)
Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640)
Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63)
Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', 'bcf230cb-01e3-4d6f-a5b1-ef311afd3147') (Line: 95)
Drupal\editor\Plugin\Filter\EditorFileReference->process('Un interesante escenario es aquel que implica una tabla de datos que incluye la "ocupación" de unos ciertos recursos indicando la fecha de comienzo y la de finalización de la ocupación, teniendo como objetivo la visualización de una gráfica en la que se muestre el calendario y los días en los que cada recurso está ocupado o disponible.
Para resolver este escenario partimos de una tabla ("<em>Allocations</em>") en la que se muestra el recurso en cuestión (1, 2 o 3 en nuestro ejemplo), y las fechas de inicio y fin de la ocupación:
Partimos también de un calendario ("<em>Calendar</em>") que, en este ejemplo, está limitado a la quincena dentro de la cual se producen las ocupaciones de cada recurso:
Si generamos un gráfico a mano -usando Excel, por ejemplo-, la visualización de las ocupaciones de cada recurso tendría el siguiente aspecto:
El objetivo es llegar a una visualización semejante que se genere de forma automática.
Obsérvese que si cruzamos la tabla "Allocations" (que incluye los períodos en los que cada recurso está reservado) y el calendario mediante la función <a href="/dax/function/generate">GENERATE</a>, por ejemplo (también valdría la función <a href="/dax/function/crossjoin">CROSSJOIN</a> pues, en este caso, no estamos haciendo uso del contexto de fila generado por las filas de la primera tabla), tendremos todas las posibles combinaciones entre las filas de ambas:
Table =
GENERATE(
Allocations;
'Calendar'
)
Y de esta tabla, es sencillo quedarnos solo con los días en los que el recurso está reservado si seleccionamos apenas aquellas filas en las que el campo <em>Date </em>sea mayor o igual a <em>Start </em>y menor o igual a <em>End</em>, para lo que recurrimos a la función <a href="/dax/function/filter">FILTER</a>:
Table =
FILTER(
GENERATE(
Allocations;
'Calendar'
);
'Calendar'[Date] >= Allocations[Start] && 'Calendar'[Date] <= Allocations[End]
)
En este punto podríamos obviar los campos <em>Start </em>y <em>End</em>, que ya no aportan nada, para lo que podemos recurrir a la función <a href="/dax/function/selectcolumns">SELECTCOLUMNS</a> que nos permite escoger qué campos queremos seleccionar:
Table =
SELECTCOLUMNS(
FILTER(
GENERATE(
Allocations;
'Calendar'
);
'Calendar'[Date] >= Allocations[Start] && 'Calendar'[Date] <= Allocations[End]
);
"Id"; Allocations[Id];
"Resource"; Allocations[Resource];
"Date"; 'Calendar'[Date]
)
Para visualizar el resultado vamos a recurrir a la visualización "<em>as Timeline</em>" descargable desde el marketplace. Una vez llevada al lienzo su configuración es la siguiente:
Y la visualización queda de la siguiente forma:
Podemos comparar el resultado con el esquema realizado a mano:
También habríamos podido aprovechar el contexto de fila creado por la función GENERATE para incluir el filtro dentro de la propia función, de la siguiente manera:
Table =
SELECTCOLUMNS(
GENERATE(
Allocations;
FILTER(
'Calendar';
'Calendar'[Date] >= Allocations[Start] && 'Calendar'[Date] <= Allocations[End]
)
);
"Id"; Allocations[Id];
"Resource"; Allocations[Resource];
"Date"; 'Calendar'[Date]
)
', 'es') (Line: 118)
Drupal\filter\Element\ProcessedText::preRenderText(Array)
call_user_func_array(Array, Array) (Line: 101)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88)
__TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 46)
__TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 43)
__TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110)
__TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, ) (Line: 242)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
- Deprecated function: Creation of dynamic property Drupal\mysql\Driver\Database\mysql\Select::$alterTags is deprecated in Drupal\Core\Database\Query\Select->addTag() (line 149 of core/lib/Drupal/Core/Database/Query/Select.php).
Drupal\Core\Database\Query\Select->addTag('entity_query') (Line: 147)
Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80)
Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640)
Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63)
Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', 'bcf230cb-01e3-4d6f-a5b1-ef311afd3147') (Line: 95)
Drupal\editor\Plugin\Filter\EditorFileReference->process('Un interesante escenario es aquel que implica una tabla de datos que incluye la "ocupación" de unos ciertos recursos indicando la fecha de comienzo y la de finalización de la ocupación, teniendo como objetivo la visualización de una gráfica en la que se muestre el calendario y los días en los que cada recurso está ocupado o disponible.
Para resolver este escenario partimos de una tabla ("<em>Allocations</em>") en la que se muestra el recurso en cuestión (1, 2 o 3 en nuestro ejemplo), y las fechas de inicio y fin de la ocupación:
Partimos también de un calendario ("<em>Calendar</em>") que, en este ejemplo, está limitado a la quincena dentro de la cual se producen las ocupaciones de cada recurso:
Si generamos un gráfico a mano -usando Excel, por ejemplo-, la visualización de las ocupaciones de cada recurso tendría el siguiente aspecto:
El objetivo es llegar a una visualización semejante que se genere de forma automática.
Obsérvese que si cruzamos la tabla "Allocations" (que incluye los períodos en los que cada recurso está reservado) y el calendario mediante la función <a href="/dax/function/generate">GENERATE</a>, por ejemplo (también valdría la función <a href="/dax/function/crossjoin">CROSSJOIN</a> pues, en este caso, no estamos haciendo uso del contexto de fila generado por las filas de la primera tabla), tendremos todas las posibles combinaciones entre las filas de ambas:
Table =
GENERATE(
Allocations;
'Calendar'
)
Y de esta tabla, es sencillo quedarnos solo con los días en los que el recurso está reservado si seleccionamos apenas aquellas filas en las que el campo <em>Date </em>sea mayor o igual a <em>Start </em>y menor o igual a <em>End</em>, para lo que recurrimos a la función <a href="/dax/function/filter">FILTER</a>:
Table =
FILTER(
GENERATE(
Allocations;
'Calendar'
);
'Calendar'[Date] >= Allocations[Start] && 'Calendar'[Date] <= Allocations[End]
)
En este punto podríamos obviar los campos <em>Start </em>y <em>End</em>, que ya no aportan nada, para lo que podemos recurrir a la función <a href="/dax/function/selectcolumns">SELECTCOLUMNS</a> que nos permite escoger qué campos queremos seleccionar:
Table =
SELECTCOLUMNS(
FILTER(
GENERATE(
Allocations;
'Calendar'
);
'Calendar'[Date] >= Allocations[Start] && 'Calendar'[Date] <= Allocations[End]
);
"Id"; Allocations[Id];
"Resource"; Allocations[Resource];
"Date"; 'Calendar'[Date]
)
Para visualizar el resultado vamos a recurrir a la visualización "<em>as Timeline</em>" descargable desde el marketplace. Una vez llevada al lienzo su configuración es la siguiente:
Y la visualización queda de la siguiente forma:
Podemos comparar el resultado con el esquema realizado a mano:
También habríamos podido aprovechar el contexto de fila creado por la función GENERATE para incluir el filtro dentro de la propia función, de la siguiente manera:
Table =
SELECTCOLUMNS(
GENERATE(
Allocations;
FILTER(
'Calendar';
'Calendar'[Date] >= Allocations[Start] && 'Calendar'[Date] <= Allocations[End]
)
);
"Id"; Allocations[Id];
"Resource"; Allocations[Resource];
"Date"; 'Calendar'[Date]
)
', 'es') (Line: 118)
Drupal\filter\Element\ProcessedText::preRenderText(Array)
call_user_func_array(Array, Array) (Line: 101)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88)
__TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 46)
__TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 43)
__TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110)
__TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, ) (Line: 242)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
- Deprecated function: Creation of dynamic property Drupal\mysql\Driver\Database\mysql\Select::$alterMetaData is deprecated in Drupal\Core\Database\Query\Select->addMetaData() (line 178 of core/lib/Drupal/Core/Database/Query/Select.php).
Drupal\Core\Database\Query\Select->addMetaData('entity_type', 'file') (Line: 115)
Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80)
Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640)
Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63)
Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', 'bcf230cb-01e3-4d6f-a5b1-ef311afd3147') (Line: 124)
Drupal\editor\Plugin\Filter\EditorFileReference->process('Un interesante escenario es aquel que implica una tabla de datos que incluye la "ocupación" de unos ciertos recursos indicando la fecha de comienzo y la de finalización de la ocupación, teniendo como objetivo la visualización de una gráfica en la que se muestre el calendario y los días en los que cada recurso está ocupado o disponible.
Para resolver este escenario partimos de una tabla ("<em>Allocations</em>") en la que se muestra el recurso en cuestión (1, 2 o 3 en nuestro ejemplo), y las fechas de inicio y fin de la ocupación:
Partimos también de un calendario ("<em>Calendar</em>") que, en este ejemplo, está limitado a la quincena dentro de la cual se producen las ocupaciones de cada recurso:
Si generamos un gráfico a mano -usando Excel, por ejemplo-, la visualización de las ocupaciones de cada recurso tendría el siguiente aspecto:
El objetivo es llegar a una visualización semejante que se genere de forma automática.
Obsérvese que si cruzamos la tabla "Allocations" (que incluye los períodos en los que cada recurso está reservado) y el calendario mediante la función <a href="/dax/function/generate">GENERATE</a>, por ejemplo (también valdría la función <a href="/dax/function/crossjoin">CROSSJOIN</a> pues, en este caso, no estamos haciendo uso del contexto de fila generado por las filas de la primera tabla), tendremos todas las posibles combinaciones entre las filas de ambas:
Table =
GENERATE(
Allocations;
'Calendar'
)
Y de esta tabla, es sencillo quedarnos solo con los días en los que el recurso está reservado si seleccionamos apenas aquellas filas en las que el campo <em>Date </em>sea mayor o igual a <em>Start </em>y menor o igual a <em>End</em>, para lo que recurrimos a la función <a href="/dax/function/filter">FILTER</a>:
Table =
FILTER(
GENERATE(
Allocations;
'Calendar'
);
'Calendar'[Date] >= Allocations[Start] && 'Calendar'[Date] <= Allocations[End]
)
En este punto podríamos obviar los campos <em>Start </em>y <em>End</em>, que ya no aportan nada, para lo que podemos recurrir a la función <a href="/dax/function/selectcolumns">SELECTCOLUMNS</a> que nos permite escoger qué campos queremos seleccionar:
Table =
SELECTCOLUMNS(
FILTER(
GENERATE(
Allocations;
'Calendar'
);
'Calendar'[Date] >= Allocations[Start] && 'Calendar'[Date] <= Allocations[End]
);
"Id"; Allocations[Id];
"Resource"; Allocations[Resource];
"Date"; 'Calendar'[Date]
)
Para visualizar el resultado vamos a recurrir a la visualización "<em>as Timeline</em>" descargable desde el marketplace. Una vez llevada al lienzo su configuración es la siguiente:
Y la visualización queda de la siguiente forma:
Podemos comparar el resultado con el esquema realizado a mano:
También habríamos podido aprovechar el contexto de fila creado por la función GENERATE para incluir el filtro dentro de la propia función, de la siguiente manera:
Table =
SELECTCOLUMNS(
GENERATE(
Allocations;
FILTER(
'Calendar';
'Calendar'[Date] >= Allocations[Start] && 'Calendar'[Date] <= Allocations[End]
)
);
"Id"; Allocations[Id];
"Resource"; Allocations[Resource];
"Date"; 'Calendar'[Date]
)
', 'es') (Line: 118)
Drupal\filter\Element\ProcessedText::preRenderText(Array)
call_user_func_array(Array, Array) (Line: 101)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88)
__TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 46)
__TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 43)
__TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110)
__TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, ) (Line: 242)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
- Deprecated function: Creation of dynamic property Drupal\mysql\Driver\Database\mysql\Select::$alterTags is deprecated in Drupal\Core\Database\Query\Select->addTag() (line 149 of core/lib/Drupal/Core/Database/Query/Select.php).
Drupal\Core\Database\Query\Select->addTag('entity_query') (Line: 147)
Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80)
Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640)
Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63)
Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', 'bcf230cb-01e3-4d6f-a5b1-ef311afd3147') (Line: 124)
Drupal\editor\Plugin\Filter\EditorFileReference->process('Un interesante escenario es aquel que implica una tabla de datos que incluye la "ocupación" de unos ciertos recursos indicando la fecha de comienzo y la de finalización de la ocupación, teniendo como objetivo la visualización de una gráfica en la que se muestre el calendario y los días en los que cada recurso está ocupado o disponible.
Para resolver este escenario partimos de una tabla ("<em>Allocations</em>") en la que se muestra el recurso en cuestión (1, 2 o 3 en nuestro ejemplo), y las fechas de inicio y fin de la ocupación:
Partimos también de un calendario ("<em>Calendar</em>") que, en este ejemplo, está limitado a la quincena dentro de la cual se producen las ocupaciones de cada recurso:
Si generamos un gráfico a mano -usando Excel, por ejemplo-, la visualización de las ocupaciones de cada recurso tendría el siguiente aspecto:
El objetivo es llegar a una visualización semejante que se genere de forma automática.
Obsérvese que si cruzamos la tabla "Allocations" (que incluye los períodos en los que cada recurso está reservado) y el calendario mediante la función <a href="/dax/function/generate">GENERATE</a>, por ejemplo (también valdría la función <a href="/dax/function/crossjoin">CROSSJOIN</a> pues, en este caso, no estamos haciendo uso del contexto de fila generado por las filas de la primera tabla), tendremos todas las posibles combinaciones entre las filas de ambas:
Table =
GENERATE(
Allocations;
'Calendar'
)
Y de esta tabla, es sencillo quedarnos solo con los días en los que el recurso está reservado si seleccionamos apenas aquellas filas en las que el campo <em>Date </em>sea mayor o igual a <em>Start </em>y menor o igual a <em>End</em>, para lo que recurrimos a la función <a href="/dax/function/filter">FILTER</a>:
Table =
FILTER(
GENERATE(
Allocations;
'Calendar'
);
'Calendar'[Date] >= Allocations[Start] && 'Calendar'[Date] <= Allocations[End]
)
En este punto podríamos obviar los campos <em>Start </em>y <em>End</em>, que ya no aportan nada, para lo que podemos recurrir a la función <a href="/dax/function/selectcolumns">SELECTCOLUMNS</a> que nos permite escoger qué campos queremos seleccionar:
Table =
SELECTCOLUMNS(
FILTER(
GENERATE(
Allocations;
'Calendar'
);
'Calendar'[Date] >= Allocations[Start] && 'Calendar'[Date] <= Allocations[End]
);
"Id"; Allocations[Id];
"Resource"; Allocations[Resource];
"Date"; 'Calendar'[Date]
)
Para visualizar el resultado vamos a recurrir a la visualización "<em>as Timeline</em>" descargable desde el marketplace. Una vez llevada al lienzo su configuración es la siguiente:
Y la visualización queda de la siguiente forma:
Podemos comparar el resultado con el esquema realizado a mano:
También habríamos podido aprovechar el contexto de fila creado por la función GENERATE para incluir el filtro dentro de la propia función, de la siguiente manera:
Table =
SELECTCOLUMNS(
GENERATE(
Allocations;
FILTER(
'Calendar';
'Calendar'[Date] >= Allocations[Start] && 'Calendar'[Date] <= Allocations[End]
)
);
"Id"; Allocations[Id];
"Resource"; Allocations[Resource];
"Date"; 'Calendar'[Date]
)
', 'es') (Line: 118)
Drupal\filter\Element\ProcessedText::preRenderText(Array)
call_user_func_array(Array, Array) (Line: 101)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88)
__TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 46)
__TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 43)
__TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110)
__TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, ) (Line: 242)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
- Deprecated function: Creation of dynamic property Drupal\mysql\Driver\Database\mysql\Select::$alterMetaData is deprecated in Drupal\Core\Database\Query\Select->addMetaData() (line 178 of core/lib/Drupal/Core/Database/Query/Select.php).
Drupal\Core\Database\Query\Select->addMetaData('entity_type', 'file') (Line: 115)
Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80)
Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640)
Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63)
Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', '69d1ad45-c287-4783-8119-e0e293da2e21') (Line: 95)
Drupal\editor\Plugin\Filter\EditorFileReference->process('Un interesante escenario es aquel que implica una tabla de datos que incluye la "ocupación" de unos ciertos recursos indicando la fecha de comienzo y la de finalización de la ocupación, teniendo como objetivo la visualización de una gráfica en la que se muestre el calendario y los días en los que cada recurso está ocupado o disponible.
Para resolver este escenario partimos de una tabla ("<em>Allocations</em>") en la que se muestra el recurso en cuestión (1, 2 o 3 en nuestro ejemplo), y las fechas de inicio y fin de la ocupación:
Partimos también de un calendario ("<em>Calendar</em>") que, en este ejemplo, está limitado a la quincena dentro de la cual se producen las ocupaciones de cada recurso:
Si generamos un gráfico a mano -usando Excel, por ejemplo-, la visualización de las ocupaciones de cada recurso tendría el siguiente aspecto:
El objetivo es llegar a una visualización semejante que se genere de forma automática.
Obsérvese que si cruzamos la tabla "Allocations" (que incluye los períodos en los que cada recurso está reservado) y el calendario mediante la función <a href="/dax/function/generate">GENERATE</a>, por ejemplo (también valdría la función <a href="/dax/function/crossjoin">CROSSJOIN</a> pues, en este caso, no estamos haciendo uso del contexto de fila generado por las filas de la primera tabla), tendremos todas las posibles combinaciones entre las filas de ambas:
Table =
GENERATE(
Allocations;
'Calendar'
)
Y de esta tabla, es sencillo quedarnos solo con los días en los que el recurso está reservado si seleccionamos apenas aquellas filas en las que el campo <em>Date </em>sea mayor o igual a <em>Start </em>y menor o igual a <em>End</em>, para lo que recurrimos a la función <a href="/dax/function/filter">FILTER</a>:
Table =
FILTER(
GENERATE(
Allocations;
'Calendar'
);
'Calendar'[Date] >= Allocations[Start] && 'Calendar'[Date] <= Allocations[End]
)
En este punto podríamos obviar los campos <em>Start </em>y <em>End</em>, que ya no aportan nada, para lo que podemos recurrir a la función <a href="/dax/function/selectcolumns">SELECTCOLUMNS</a> que nos permite escoger qué campos queremos seleccionar:
Table =
SELECTCOLUMNS(
FILTER(
GENERATE(
Allocations;
'Calendar'
);
'Calendar'[Date] >= Allocations[Start] && 'Calendar'[Date] <= Allocations[End]
);
"Id"; Allocations[Id];
"Resource"; Allocations[Resource];
"Date"; 'Calendar'[Date]
)
Para visualizar el resultado vamos a recurrir a la visualización "<em>as Timeline</em>" descargable desde el marketplace. Una vez llevada al lienzo su configuración es la siguiente:
Y la visualización queda de la siguiente forma:
Podemos comparar el resultado con el esquema realizado a mano:
También habríamos podido aprovechar el contexto de fila creado por la función GENERATE para incluir el filtro dentro de la propia función, de la siguiente manera:
Table =
SELECTCOLUMNS(
GENERATE(
Allocations;
FILTER(
'Calendar';
'Calendar'[Date] >= Allocations[Start] && 'Calendar'[Date] <= Allocations[End]
)
);
"Id"; Allocations[Id];
"Resource"; Allocations[Resource];
"Date"; 'Calendar'[Date]
)
', 'es') (Line: 118)
Drupal\filter\Element\ProcessedText::preRenderText(Array)
call_user_func_array(Array, Array) (Line: 101)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88)
__TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 46)
__TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 43)
__TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110)
__TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, ) (Line: 242)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
- Deprecated function: Creation of dynamic property Drupal\mysql\Driver\Database\mysql\Select::$alterTags is deprecated in Drupal\Core\Database\Query\Select->addTag() (line 149 of core/lib/Drupal/Core/Database/Query/Select.php).
Drupal\Core\Database\Query\Select->addTag('entity_query') (Line: 147)
Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80)
Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640)
Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63)
Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', '69d1ad45-c287-4783-8119-e0e293da2e21') (Line: 95)
Drupal\editor\Plugin\Filter\EditorFileReference->process('Un interesante escenario es aquel que implica una tabla de datos que incluye la "ocupación" de unos ciertos recursos indicando la fecha de comienzo y la de finalización de la ocupación, teniendo como objetivo la visualización de una gráfica en la que se muestre el calendario y los días en los que cada recurso está ocupado o disponible.
Para resolver este escenario partimos de una tabla ("<em>Allocations</em>") en la que se muestra el recurso en cuestión (1, 2 o 3 en nuestro ejemplo), y las fechas de inicio y fin de la ocupación:
Partimos también de un calendario ("<em>Calendar</em>") que, en este ejemplo, está limitado a la quincena dentro de la cual se producen las ocupaciones de cada recurso:
Si generamos un gráfico a mano -usando Excel, por ejemplo-, la visualización de las ocupaciones de cada recurso tendría el siguiente aspecto:
El objetivo es llegar a una visualización semejante que se genere de forma automática.
Obsérvese que si cruzamos la tabla "Allocations" (que incluye los períodos en los que cada recurso está reservado) y el calendario mediante la función <a href="/dax/function/generate">GENERATE</a>, por ejemplo (también valdría la función <a href="/dax/function/crossjoin">CROSSJOIN</a> pues, en este caso, no estamos haciendo uso del contexto de fila generado por las filas de la primera tabla), tendremos todas las posibles combinaciones entre las filas de ambas:
Table =
GENERATE(
Allocations;
'Calendar'
)
Y de esta tabla, es sencillo quedarnos solo con los días en los que el recurso está reservado si seleccionamos apenas aquellas filas en las que el campo <em>Date </em>sea mayor o igual a <em>Start </em>y menor o igual a <em>End</em>, para lo que recurrimos a la función <a href="/dax/function/filter">FILTER</a>:
Table =
FILTER(
GENERATE(
Allocations;
'Calendar'
);
'Calendar'[Date] >= Allocations[Start] && 'Calendar'[Date] <= Allocations[End]
)
En este punto podríamos obviar los campos <em>Start </em>y <em>End</em>, que ya no aportan nada, para lo que podemos recurrir a la función <a href="/dax/function/selectcolumns">SELECTCOLUMNS</a> que nos permite escoger qué campos queremos seleccionar:
Table =
SELECTCOLUMNS(
FILTER(
GENERATE(
Allocations;
'Calendar'
);
'Calendar'[Date] >= Allocations[Start] && 'Calendar'[Date] <= Allocations[End]
);
"Id"; Allocations[Id];
"Resource"; Allocations[Resource];
"Date"; 'Calendar'[Date]
)
Para visualizar el resultado vamos a recurrir a la visualización "<em>as Timeline</em>" descargable desde el marketplace. Una vez llevada al lienzo su configuración es la siguiente:
Y la visualización queda de la siguiente forma:
Podemos comparar el resultado con el esquema realizado a mano:
También habríamos podido aprovechar el contexto de fila creado por la función GENERATE para incluir el filtro dentro de la propia función, de la siguiente manera:
Table =
SELECTCOLUMNS(
GENERATE(
Allocations;
FILTER(
'Calendar';
'Calendar'[Date] >= Allocations[Start] && 'Calendar'[Date] <= Allocations[End]
)
);
"Id"; Allocations[Id];
"Resource"; Allocations[Resource];
"Date"; 'Calendar'[Date]
)
', 'es') (Line: 118)
Drupal\filter\Element\ProcessedText::preRenderText(Array)
call_user_func_array(Array, Array) (Line: 101)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88)
__TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 46)
__TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 43)
__TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110)
__TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, ) (Line: 242)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
- Deprecated function: Creation of dynamic property Drupal\mysql\Driver\Database\mysql\Select::$alterMetaData is deprecated in Drupal\Core\Database\Query\Select->addMetaData() (line 178 of core/lib/Drupal/Core/Database/Query/Select.php).
Drupal\Core\Database\Query\Select->addMetaData('entity_type', 'file') (Line: 115)
Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80)
Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640)
Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63)
Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', '69d1ad45-c287-4783-8119-e0e293da2e21') (Line: 124)
Drupal\editor\Plugin\Filter\EditorFileReference->process('Un interesante escenario es aquel que implica una tabla de datos que incluye la "ocupación" de unos ciertos recursos indicando la fecha de comienzo y la de finalización de la ocupación, teniendo como objetivo la visualización de una gráfica en la que se muestre el calendario y los días en los que cada recurso está ocupado o disponible.
Para resolver este escenario partimos de una tabla ("<em>Allocations</em>") en la que se muestra el recurso en cuestión (1, 2 o 3 en nuestro ejemplo), y las fechas de inicio y fin de la ocupación:
Partimos también de un calendario ("<em>Calendar</em>") que, en este ejemplo, está limitado a la quincena dentro de la cual se producen las ocupaciones de cada recurso:
Si generamos un gráfico a mano -usando Excel, por ejemplo-, la visualización de las ocupaciones de cada recurso tendría el siguiente aspecto:
El objetivo es llegar a una visualización semejante que se genere de forma automática.
Obsérvese que si cruzamos la tabla "Allocations" (que incluye los períodos en los que cada recurso está reservado) y el calendario mediante la función <a href="/dax/function/generate">GENERATE</a>, por ejemplo (también valdría la función <a href="/dax/function/crossjoin">CROSSJOIN</a> pues, en este caso, no estamos haciendo uso del contexto de fila generado por las filas de la primera tabla), tendremos todas las posibles combinaciones entre las filas de ambas:
Table =
GENERATE(
Allocations;
'Calendar'
)
Y de esta tabla, es sencillo quedarnos solo con los días en los que el recurso está reservado si seleccionamos apenas aquellas filas en las que el campo <em>Date </em>sea mayor o igual a <em>Start </em>y menor o igual a <em>End</em>, para lo que recurrimos a la función <a href="/dax/function/filter">FILTER</a>:
Table =
FILTER(
GENERATE(
Allocations;
'Calendar'
);
'Calendar'[Date] >= Allocations[Start] && 'Calendar'[Date] <= Allocations[End]
)
En este punto podríamos obviar los campos <em>Start </em>y <em>End</em>, que ya no aportan nada, para lo que podemos recurrir a la función <a href="/dax/function/selectcolumns">SELECTCOLUMNS</a> que nos permite escoger qué campos queremos seleccionar:
Table =
SELECTCOLUMNS(
FILTER(
GENERATE(
Allocations;
'Calendar'
);
'Calendar'[Date] >= Allocations[Start] && 'Calendar'[Date] <= Allocations[End]
);
"Id"; Allocations[Id];
"Resource"; Allocations[Resource];
"Date"; 'Calendar'[Date]
)
Para visualizar el resultado vamos a recurrir a la visualización "<em>as Timeline</em>" descargable desde el marketplace. Una vez llevada al lienzo su configuración es la siguiente:
Y la visualización queda de la siguiente forma:
Podemos comparar el resultado con el esquema realizado a mano:
También habríamos podido aprovechar el contexto de fila creado por la función GENERATE para incluir el filtro dentro de la propia función, de la siguiente manera:
Table =
SELECTCOLUMNS(
GENERATE(
Allocations;
FILTER(
'Calendar';
'Calendar'[Date] >= Allocations[Start] && 'Calendar'[Date] <= Allocations[End]
)
);
"Id"; Allocations[Id];
"Resource"; Allocations[Resource];
"Date"; 'Calendar'[Date]
)
', 'es') (Line: 118)
Drupal\filter\Element\ProcessedText::preRenderText(Array)
call_user_func_array(Array, Array) (Line: 101)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88)
__TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 46)
__TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 43)
__TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110)
__TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, ) (Line: 242)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
- Deprecated function: Creation of dynamic property Drupal\mysql\Driver\Database\mysql\Select::$alterTags is deprecated in Drupal\Core\Database\Query\Select->addTag() (line 149 of core/lib/Drupal/Core/Database/Query/Select.php).
Drupal\Core\Database\Query\Select->addTag('entity_query') (Line: 147)
Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80)
Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640)
Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63)
Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', '69d1ad45-c287-4783-8119-e0e293da2e21') (Line: 124)
Drupal\editor\Plugin\Filter\EditorFileReference->process('Un interesante escenario es aquel que implica una tabla de datos que incluye la "ocupación" de unos ciertos recursos indicando la fecha de comienzo y la de finalización de la ocupación, teniendo como objetivo la visualización de una gráfica en la que se muestre el calendario y los días en los que cada recurso está ocupado o disponible.
Para resolver este escenario partimos de una tabla ("<em>Allocations</em>") en la que se muestra el recurso en cuestión (1, 2 o 3 en nuestro ejemplo), y las fechas de inicio y fin de la ocupación:
Partimos también de un calendario ("<em>Calendar</em>") que, en este ejemplo, está limitado a la quincena dentro de la cual se producen las ocupaciones de cada recurso:
Si generamos un gráfico a mano -usando Excel, por ejemplo-, la visualización de las ocupaciones de cada recurso tendría el siguiente aspecto:
El objetivo es llegar a una visualización semejante que se genere de forma automática.
Obsérvese que si cruzamos la tabla "Allocations" (que incluye los períodos en los que cada recurso está reservado) y el calendario mediante la función <a href="/dax/function/generate">GENERATE</a>, por ejemplo (también valdría la función <a href="/dax/function/crossjoin">CROSSJOIN</a> pues, en este caso, no estamos haciendo uso del contexto de fila generado por las filas de la primera tabla), tendremos todas las posibles combinaciones entre las filas de ambas:
Table =
GENERATE(
Allocations;
'Calendar'
)
Y de esta tabla, es sencillo quedarnos solo con los días en los que el recurso está reservado si seleccionamos apenas aquellas filas en las que el campo <em>Date </em>sea mayor o igual a <em>Start </em>y menor o igual a <em>End</em>, para lo que recurrimos a la función <a href="/dax/function/filter">FILTER</a>:
Table =
FILTER(
GENERATE(
Allocations;
'Calendar'
);
'Calendar'[Date] >= Allocations[Start] && 'Calendar'[Date] <= Allocations[End]
)
En este punto podríamos obviar los campos <em>Start </em>y <em>End</em>, que ya no aportan nada, para lo que podemos recurrir a la función <a href="/dax/function/selectcolumns">SELECTCOLUMNS</a> que nos permite escoger qué campos queremos seleccionar:
Table =
SELECTCOLUMNS(
FILTER(
GENERATE(
Allocations;
'Calendar'
);
'Calendar'[Date] >= Allocations[Start] && 'Calendar'[Date] <= Allocations[End]
);
"Id"; Allocations[Id];
"Resource"; Allocations[Resource];
"Date"; 'Calendar'[Date]
)
Para visualizar el resultado vamos a recurrir a la visualización "<em>as Timeline</em>" descargable desde el marketplace. Una vez llevada al lienzo su configuración es la siguiente:
Y la visualización queda de la siguiente forma:
Podemos comparar el resultado con el esquema realizado a mano:
También habríamos podido aprovechar el contexto de fila creado por la función GENERATE para incluir el filtro dentro de la propia función, de la siguiente manera:
Table =
SELECTCOLUMNS(
GENERATE(
Allocations;
FILTER(
'Calendar';
'Calendar'[Date] >= Allocations[Start] && 'Calendar'[Date] <= Allocations[End]
)
);
"Id"; Allocations[Id];
"Resource"; Allocations[Resource];
"Date"; 'Calendar'[Date]
)
', 'es') (Line: 118)
Drupal\filter\Element\ProcessedText::preRenderText(Array)
call_user_func_array(Array, Array) (Line: 101)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88)
__TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 46)
__TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 43)
__TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110)
__TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, ) (Line: 242)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
- Deprecated function: Creation of dynamic property Drupal\mysql\Driver\Database\mysql\Select::$alterMetaData is deprecated in Drupal\Core\Database\Query\Select->addMetaData() (line 178 of core/lib/Drupal/Core/Database/Query/Select.php).
Drupal\Core\Database\Query\Select->addMetaData('entity_type', 'file') (Line: 115)
Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80)
Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640)
Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63)
Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', '2edb3b99-714c-48b8-b589-d9be27b4a8c1') (Line: 95)
Drupal\editor\Plugin\Filter\EditorFileReference->process('Un interesante escenario es aquel que implica una tabla de datos que incluye la "ocupación" de unos ciertos recursos indicando la fecha de comienzo y la de finalización de la ocupación, teniendo como objetivo la visualización de una gráfica en la que se muestre el calendario y los días en los que cada recurso está ocupado o disponible.
Para resolver este escenario partimos de una tabla ("<em>Allocations</em>") en la que se muestra el recurso en cuestión (1, 2 o 3 en nuestro ejemplo), y las fechas de inicio y fin de la ocupación:
Partimos también de un calendario ("<em>Calendar</em>") que, en este ejemplo, está limitado a la quincena dentro de la cual se producen las ocupaciones de cada recurso:
Si generamos un gráfico a mano -usando Excel, por ejemplo-, la visualización de las ocupaciones de cada recurso tendría el siguiente aspecto:
El objetivo es llegar a una visualización semejante que se genere de forma automática.
Obsérvese que si cruzamos la tabla "Allocations" (que incluye los períodos en los que cada recurso está reservado) y el calendario mediante la función <a href="/dax/function/generate">GENERATE</a>, por ejemplo (también valdría la función <a href="/dax/function/crossjoin">CROSSJOIN</a> pues, en este caso, no estamos haciendo uso del contexto de fila generado por las filas de la primera tabla), tendremos todas las posibles combinaciones entre las filas de ambas:
Table =
GENERATE(
Allocations;
'Calendar'
)
Y de esta tabla, es sencillo quedarnos solo con los días en los que el recurso está reservado si seleccionamos apenas aquellas filas en las que el campo <em>Date </em>sea mayor o igual a <em>Start </em>y menor o igual a <em>End</em>, para lo que recurrimos a la función <a href="/dax/function/filter">FILTER</a>:
Table =
FILTER(
GENERATE(
Allocations;
'Calendar'
);
'Calendar'[Date] >= Allocations[Start] && 'Calendar'[Date] <= Allocations[End]
)
En este punto podríamos obviar los campos <em>Start </em>y <em>End</em>, que ya no aportan nada, para lo que podemos recurrir a la función <a href="/dax/function/selectcolumns">SELECTCOLUMNS</a> que nos permite escoger qué campos queremos seleccionar:
Table =
SELECTCOLUMNS(
FILTER(
GENERATE(
Allocations;
'Calendar'
);
'Calendar'[Date] >= Allocations[Start] && 'Calendar'[Date] <= Allocations[End]
);
"Id"; Allocations[Id];
"Resource"; Allocations[Resource];
"Date"; 'Calendar'[Date]
)
Para visualizar el resultado vamos a recurrir a la visualización "<em>as Timeline</em>" descargable desde el marketplace. Una vez llevada al lienzo su configuración es la siguiente:
Y la visualización queda de la siguiente forma:
Podemos comparar el resultado con el esquema realizado a mano:
También habríamos podido aprovechar el contexto de fila creado por la función GENERATE para incluir el filtro dentro de la propia función, de la siguiente manera:
Table =
SELECTCOLUMNS(
GENERATE(
Allocations;
FILTER(
'Calendar';
'Calendar'[Date] >= Allocations[Start] && 'Calendar'[Date] <= Allocations[End]
)
);
"Id"; Allocations[Id];
"Resource"; Allocations[Resource];
"Date"; 'Calendar'[Date]
)
', 'es') (Line: 118)
Drupal\filter\Element\ProcessedText::preRenderText(Array)
call_user_func_array(Array, Array) (Line: 101)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88)
__TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 46)
__TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 43)
__TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110)
__TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, ) (Line: 242)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
- Deprecated function: Creation of dynamic property Drupal\mysql\Driver\Database\mysql\Select::$alterTags is deprecated in Drupal\Core\Database\Query\Select->addTag() (line 149 of core/lib/Drupal/Core/Database/Query/Select.php).
Drupal\Core\Database\Query\Select->addTag('entity_query') (Line: 147)
Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80)
Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640)
Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63)
Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', '2edb3b99-714c-48b8-b589-d9be27b4a8c1') (Line: 95)
Drupal\editor\Plugin\Filter\EditorFileReference->process('Un interesante escenario es aquel que implica una tabla de datos que incluye la "ocupación" de unos ciertos recursos indicando la fecha de comienzo y la de finalización de la ocupación, teniendo como objetivo la visualización de una gráfica en la que se muestre el calendario y los días en los que cada recurso está ocupado o disponible.
Para resolver este escenario partimos de una tabla ("<em>Allocations</em>") en la que se muestra el recurso en cuestión (1, 2 o 3 en nuestro ejemplo), y las fechas de inicio y fin de la ocupación:
Partimos también de un calendario ("<em>Calendar</em>") que, en este ejemplo, está limitado a la quincena dentro de la cual se producen las ocupaciones de cada recurso:
Si generamos un gráfico a mano -usando Excel, por ejemplo-, la visualización de las ocupaciones de cada recurso tendría el siguiente aspecto:
El objetivo es llegar a una visualización semejante que se genere de forma automática.
Obsérvese que si cruzamos la tabla "Allocations" (que incluye los períodos en los que cada recurso está reservado) y el calendario mediante la función <a href="/dax/function/generate">GENERATE</a>, por ejemplo (también valdría la función <a href="/dax/function/crossjoin">CROSSJOIN</a> pues, en este caso, no estamos haciendo uso del contexto de fila generado por las filas de la primera tabla), tendremos todas las posibles combinaciones entre las filas de ambas:
Table =
GENERATE(
Allocations;
'Calendar'
)
Y de esta tabla, es sencillo quedarnos solo con los días en los que el recurso está reservado si seleccionamos apenas aquellas filas en las que el campo <em>Date </em>sea mayor o igual a <em>Start </em>y menor o igual a <em>End</em>, para lo que recurrimos a la función <a href="/dax/function/filter">FILTER</a>:
Table =
FILTER(
GENERATE(
Allocations;
'Calendar'
);
'Calendar'[Date] >= Allocations[Start] && 'Calendar'[Date] <= Allocations[End]
)
En este punto podríamos obviar los campos <em>Start </em>y <em>End</em>, que ya no aportan nada, para lo que podemos recurrir a la función <a href="/dax/function/selectcolumns">SELECTCOLUMNS</a> que nos permite escoger qué campos queremos seleccionar:
Table =
SELECTCOLUMNS(
FILTER(
GENERATE(
Allocations;
'Calendar'
);
'Calendar'[Date] >= Allocations[Start] && 'Calendar'[Date] <= Allocations[End]
);
"Id"; Allocations[Id];
"Resource"; Allocations[Resource];
"Date"; 'Calendar'[Date]
)
Para visualizar el resultado vamos a recurrir a la visualización "<em>as Timeline</em>" descargable desde el marketplace. Una vez llevada al lienzo su configuración es la siguiente:
Y la visualización queda de la siguiente forma:
Podemos comparar el resultado con el esquema realizado a mano:
También habríamos podido aprovechar el contexto de fila creado por la función GENERATE para incluir el filtro dentro de la propia función, de la siguiente manera:
Table =
SELECTCOLUMNS(
GENERATE(
Allocations;
FILTER(
'Calendar';
'Calendar'[Date] >= Allocations[Start] && 'Calendar'[Date] <= Allocations[End]
)
);
"Id"; Allocations[Id];
"Resource"; Allocations[Resource];
"Date"; 'Calendar'[Date]
)
', 'es') (Line: 118)
Drupal\filter\Element\ProcessedText::preRenderText(Array)
call_user_func_array(Array, Array) (Line: 101)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88)
__TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 46)
__TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 43)
__TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110)
__TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, ) (Line: 242)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
- Deprecated function: Creation of dynamic property Drupal\mysql\Driver\Database\mysql\Select::$alterMetaData is deprecated in Drupal\Core\Database\Query\Select->addMetaData() (line 178 of core/lib/Drupal/Core/Database/Query/Select.php).
Drupal\Core\Database\Query\Select->addMetaData('entity_type', 'file') (Line: 115)
Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80)
Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640)
Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63)
Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', '2edb3b99-714c-48b8-b589-d9be27b4a8c1') (Line: 124)
Drupal\editor\Plugin\Filter\EditorFileReference->process('Un interesante escenario es aquel que implica una tabla de datos que incluye la "ocupación" de unos ciertos recursos indicando la fecha de comienzo y la de finalización de la ocupación, teniendo como objetivo la visualización de una gráfica en la que se muestre el calendario y los días en los que cada recurso está ocupado o disponible.
Para resolver este escenario partimos de una tabla ("<em>Allocations</em>") en la que se muestra el recurso en cuestión (1, 2 o 3 en nuestro ejemplo), y las fechas de inicio y fin de la ocupación:
Partimos también de un calendario ("<em>Calendar</em>") que, en este ejemplo, está limitado a la quincena dentro de la cual se producen las ocupaciones de cada recurso:
Si generamos un gráfico a mano -usando Excel, por ejemplo-, la visualización de las ocupaciones de cada recurso tendría el siguiente aspecto:
El objetivo es llegar a una visualización semejante que se genere de forma automática.
Obsérvese que si cruzamos la tabla "Allocations" (que incluye los períodos en los que cada recurso está reservado) y el calendario mediante la función <a href="/dax/function/generate">GENERATE</a>, por ejemplo (también valdría la función <a href="/dax/function/crossjoin">CROSSJOIN</a> pues, en este caso, no estamos haciendo uso del contexto de fila generado por las filas de la primera tabla), tendremos todas las posibles combinaciones entre las filas de ambas:
Table =
GENERATE(
Allocations;
'Calendar'
)
Y de esta tabla, es sencillo quedarnos solo con los días en los que el recurso está reservado si seleccionamos apenas aquellas filas en las que el campo <em>Date </em>sea mayor o igual a <em>Start </em>y menor o igual a <em>End</em>, para lo que recurrimos a la función <a href="/dax/function/filter">FILTER</a>:
Table =
FILTER(
GENERATE(
Allocations;
'Calendar'
);
'Calendar'[Date] >= Allocations[Start] && 'Calendar'[Date] <= Allocations[End]
)
En este punto podríamos obviar los campos <em>Start </em>y <em>End</em>, que ya no aportan nada, para lo que podemos recurrir a la función <a href="/dax/function/selectcolumns">SELECTCOLUMNS</a> que nos permite escoger qué campos queremos seleccionar:
Table =
SELECTCOLUMNS(
FILTER(
GENERATE(
Allocations;
'Calendar'
);
'Calendar'[Date] >= Allocations[Start] && 'Calendar'[Date] <= Allocations[End]
);
"Id"; Allocations[Id];
"Resource"; Allocations[Resource];
"Date"; 'Calendar'[Date]
)
Para visualizar el resultado vamos a recurrir a la visualización "<em>as Timeline</em>" descargable desde el marketplace. Una vez llevada al lienzo su configuración es la siguiente:
Y la visualización queda de la siguiente forma:
Podemos comparar el resultado con el esquema realizado a mano:
También habríamos podido aprovechar el contexto de fila creado por la función GENERATE para incluir el filtro dentro de la propia función, de la siguiente manera:
Table =
SELECTCOLUMNS(
GENERATE(
Allocations;
FILTER(
'Calendar';
'Calendar'[Date] >= Allocations[Start] && 'Calendar'[Date] <= Allocations[End]
)
);
"Id"; Allocations[Id];
"Resource"; Allocations[Resource];
"Date"; 'Calendar'[Date]
)
', 'es') (Line: 118)
Drupal\filter\Element\ProcessedText::preRenderText(Array)
call_user_func_array(Array, Array) (Line: 101)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88)
__TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 46)
__TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 43)
__TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110)
__TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, ) (Line: 242)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
- Deprecated function: Creation of dynamic property Drupal\mysql\Driver\Database\mysql\Select::$alterTags is deprecated in Drupal\Core\Database\Query\Select->addTag() (line 149 of core/lib/Drupal/Core/Database/Query/Select.php).
Drupal\Core\Database\Query\Select->addTag('entity_query') (Line: 147)
Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80)
Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640)
Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63)
Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', '2edb3b99-714c-48b8-b589-d9be27b4a8c1') (Line: 124)
Drupal\editor\Plugin\Filter\EditorFileReference->process('Un interesante escenario es aquel que implica una tabla de datos que incluye la "ocupación" de unos ciertos recursos indicando la fecha de comienzo y la de finalización de la ocupación, teniendo como objetivo la visualización de una gráfica en la que se muestre el calendario y los días en los que cada recurso está ocupado o disponible.
Para resolver este escenario partimos de una tabla ("<em>Allocations</em>") en la que se muestra el recurso en cuestión (1, 2 o 3 en nuestro ejemplo), y las fechas de inicio y fin de la ocupación:
Partimos también de un calendario ("<em>Calendar</em>") que, en este ejemplo, está limitado a la quincena dentro de la cual se producen las ocupaciones de cada recurso:
Si generamos un gráfico a mano -usando Excel, por ejemplo-, la visualización de las ocupaciones de cada recurso tendría el siguiente aspecto:
El objetivo es llegar a una visualización semejante que se genere de forma automática.
Obsérvese que si cruzamos la tabla "Allocations" (que incluye los períodos en los que cada recurso está reservado) y el calendario mediante la función <a href="/dax/function/generate">GENERATE</a>, por ejemplo (también valdría la función <a href="/dax/function/crossjoin">CROSSJOIN</a> pues, en este caso, no estamos haciendo uso del contexto de fila generado por las filas de la primera tabla), tendremos todas las posibles combinaciones entre las filas de ambas:
Table =
GENERATE(
Allocations;
'Calendar'
)
Y de esta tabla, es sencillo quedarnos solo con los días en los que el recurso está reservado si seleccionamos apenas aquellas filas en las que el campo <em>Date </em>sea mayor o igual a <em>Start </em>y menor o igual a <em>End</em>, para lo que recurrimos a la función <a href="/dax/function/filter">FILTER</a>:
Table =
FILTER(
GENERATE(
Allocations;
'Calendar'
);
'Calendar'[Date] >= Allocations[Start] && 'Calendar'[Date] <= Allocations[End]
)
En este punto podríamos obviar los campos <em>Start </em>y <em>End</em>, que ya no aportan nada, para lo que podemos recurrir a la función <a href="/dax/function/selectcolumns">SELECTCOLUMNS</a> que nos permite escoger qué campos queremos seleccionar:
Table =
SELECTCOLUMNS(
FILTER(
GENERATE(
Allocations;
'Calendar'
);
'Calendar'[Date] >= Allocations[Start] && 'Calendar'[Date] <= Allocations[End]
);
"Id"; Allocations[Id];
"Resource"; Allocations[Resource];
"Date"; 'Calendar'[Date]
)
Para visualizar el resultado vamos a recurrir a la visualización "<em>as Timeline</em>" descargable desde el marketplace. Una vez llevada al lienzo su configuración es la siguiente:
Y la visualización queda de la siguiente forma:
Podemos comparar el resultado con el esquema realizado a mano:
También habríamos podido aprovechar el contexto de fila creado por la función GENERATE para incluir el filtro dentro de la propia función, de la siguiente manera:
Table =
SELECTCOLUMNS(
GENERATE(
Allocations;
FILTER(
'Calendar';
'Calendar'[Date] >= Allocations[Start] && 'Calendar'[Date] <= Allocations[End]
)
);
"Id"; Allocations[Id];
"Resource"; Allocations[Resource];
"Date"; 'Calendar'[Date]
)
', 'es') (Line: 118)
Drupal\filter\Element\ProcessedText::preRenderText(Array)
call_user_func_array(Array, Array) (Line: 101)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88)
__TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 46)
__TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 43)
__TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110)
__TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, ) (Line: 242)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
- Deprecated function: Creation of dynamic property Drupal\mysql\Driver\Database\mysql\Select::$alterMetaData is deprecated in Drupal\Core\Database\Query\Select->addMetaData() (line 178 of core/lib/Drupal/Core/Database/Query/Select.php).
Drupal\Core\Database\Query\Select->addMetaData('entity_type', 'file') (Line: 115)
Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80)
Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640)
Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63)
Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', '27c857a1-7798-4b5a-9041-8e28cd68b77e') (Line: 95)
Drupal\editor\Plugin\Filter\EditorFileReference->process('Un interesante escenario es aquel que implica una tabla de datos que incluye la "ocupación" de unos ciertos recursos indicando la fecha de comienzo y la de finalización de la ocupación, teniendo como objetivo la visualización de una gráfica en la que se muestre el calendario y los días en los que cada recurso está ocupado o disponible.
Para resolver este escenario partimos de una tabla ("<em>Allocations</em>") en la que se muestra el recurso en cuestión (1, 2 o 3 en nuestro ejemplo), y las fechas de inicio y fin de la ocupación:
Partimos también de un calendario ("<em>Calendar</em>") que, en este ejemplo, está limitado a la quincena dentro de la cual se producen las ocupaciones de cada recurso:
Si generamos un gráfico a mano -usando Excel, por ejemplo-, la visualización de las ocupaciones de cada recurso tendría el siguiente aspecto:
El objetivo es llegar a una visualización semejante que se genere de forma automática.
Obsérvese que si cruzamos la tabla "Allocations" (que incluye los períodos en los que cada recurso está reservado) y el calendario mediante la función <a href="/dax/function/generate">GENERATE</a>, por ejemplo (también valdría la función <a href="/dax/function/crossjoin">CROSSJOIN</a> pues, en este caso, no estamos haciendo uso del contexto de fila generado por las filas de la primera tabla), tendremos todas las posibles combinaciones entre las filas de ambas:
Table =
GENERATE(
Allocations;
'Calendar'
)
Y de esta tabla, es sencillo quedarnos solo con los días en los que el recurso está reservado si seleccionamos apenas aquellas filas en las que el campo <em>Date </em>sea mayor o igual a <em>Start </em>y menor o igual a <em>End</em>, para lo que recurrimos a la función <a href="/dax/function/filter">FILTER</a>:
Table =
FILTER(
GENERATE(
Allocations;
'Calendar'
);
'Calendar'[Date] >= Allocations[Start] && 'Calendar'[Date] <= Allocations[End]
)
En este punto podríamos obviar los campos <em>Start </em>y <em>End</em>, que ya no aportan nada, para lo que podemos recurrir a la función <a href="/dax/function/selectcolumns">SELECTCOLUMNS</a> que nos permite escoger qué campos queremos seleccionar:
Table =
SELECTCOLUMNS(
FILTER(
GENERATE(
Allocations;
'Calendar'
);
'Calendar'[Date] >= Allocations[Start] && 'Calendar'[Date] <= Allocations[End]
);
"Id"; Allocations[Id];
"Resource"; Allocations[Resource];
"Date"; 'Calendar'[Date]
)
Para visualizar el resultado vamos a recurrir a la visualización "<em>as Timeline</em>" descargable desde el marketplace. Una vez llevada al lienzo su configuración es la siguiente:
Y la visualización queda de la siguiente forma:
Podemos comparar el resultado con el esquema realizado a mano:
También habríamos podido aprovechar el contexto de fila creado por la función GENERATE para incluir el filtro dentro de la propia función, de la siguiente manera:
Table =
SELECTCOLUMNS(
GENERATE(
Allocations;
FILTER(
'Calendar';
'Calendar'[Date] >= Allocations[Start] && 'Calendar'[Date] <= Allocations[End]
)
);
"Id"; Allocations[Id];
"Resource"; Allocations[Resource];
"Date"; 'Calendar'[Date]
)
', 'es') (Line: 118)
Drupal\filter\Element\ProcessedText::preRenderText(Array)
call_user_func_array(Array, Array) (Line: 101)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88)
__TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 46)
__TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 43)
__TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110)
__TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, ) (Line: 242)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
- Deprecated function: Creation of dynamic property Drupal\mysql\Driver\Database\mysql\Select::$alterTags is deprecated in Drupal\Core\Database\Query\Select->addTag() (line 149 of core/lib/Drupal/Core/Database/Query/Select.php).
Drupal\Core\Database\Query\Select->addTag('entity_query') (Line: 147)
Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80)
Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640)
Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63)
Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', '27c857a1-7798-4b5a-9041-8e28cd68b77e') (Line: 95)
Drupal\editor\Plugin\Filter\EditorFileReference->process('Un interesante escenario es aquel que implica una tabla de datos que incluye la "ocupación" de unos ciertos recursos indicando la fecha de comienzo y la de finalización de la ocupación, teniendo como objetivo la visualización de una gráfica en la que se muestre el calendario y los días en los que cada recurso está ocupado o disponible.
Para resolver este escenario partimos de una tabla ("<em>Allocations</em>") en la que se muestra el recurso en cuestión (1, 2 o 3 en nuestro ejemplo), y las fechas de inicio y fin de la ocupación:
Partimos también de un calendario ("<em>Calendar</em>") que, en este ejemplo, está limitado a la quincena dentro de la cual se producen las ocupaciones de cada recurso:
Si generamos un gráfico a mano -usando Excel, por ejemplo-, la visualización de las ocupaciones de cada recurso tendría el siguiente aspecto:
El objetivo es llegar a una visualización semejante que se genere de forma automática.
Obsérvese que si cruzamos la tabla "Allocations" (que incluye los períodos en los que cada recurso está reservado) y el calendario mediante la función <a href="/dax/function/generate">GENERATE</a>, por ejemplo (también valdría la función <a href="/dax/function/crossjoin">CROSSJOIN</a> pues, en este caso, no estamos haciendo uso del contexto de fila generado por las filas de la primera tabla), tendremos todas las posibles combinaciones entre las filas de ambas:
Table =
GENERATE(
Allocations;
'Calendar'
)
Y de esta tabla, es sencillo quedarnos solo con los días en los que el recurso está reservado si seleccionamos apenas aquellas filas en las que el campo <em>Date </em>sea mayor o igual a <em>Start </em>y menor o igual a <em>End</em>, para lo que recurrimos a la función <a href="/dax/function/filter">FILTER</a>:
Table =
FILTER(
GENERATE(
Allocations;
'Calendar'
);
'Calendar'[Date] >= Allocations[Start] && 'Calendar'[Date] <= Allocations[End]
)
En este punto podríamos obviar los campos <em>Start </em>y <em>End</em>, que ya no aportan nada, para lo que podemos recurrir a la función <a href="/dax/function/selectcolumns">SELECTCOLUMNS</a> que nos permite escoger qué campos queremos seleccionar:
Table =
SELECTCOLUMNS(
FILTER(
GENERATE(
Allocations;
'Calendar'
);
'Calendar'[Date] >= Allocations[Start] && 'Calendar'[Date] <= Allocations[End]
);
"Id"; Allocations[Id];
"Resource"; Allocations[Resource];
"Date"; 'Calendar'[Date]
)
Para visualizar el resultado vamos a recurrir a la visualización "<em>as Timeline</em>" descargable desde el marketplace. Una vez llevada al lienzo su configuración es la siguiente:
Y la visualización queda de la siguiente forma:
Podemos comparar el resultado con el esquema realizado a mano:
También habríamos podido aprovechar el contexto de fila creado por la función GENERATE para incluir el filtro dentro de la propia función, de la siguiente manera:
Table =
SELECTCOLUMNS(
GENERATE(
Allocations;
FILTER(
'Calendar';
'Calendar'[Date] >= Allocations[Start] && 'Calendar'[Date] <= Allocations[End]
)
);
"Id"; Allocations[Id];
"Resource"; Allocations[Resource];
"Date"; 'Calendar'[Date]
)
', 'es') (Line: 118)
Drupal\filter\Element\ProcessedText::preRenderText(Array)
call_user_func_array(Array, Array) (Line: 101)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88)
__TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 46)
__TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 43)
__TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110)
__TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, ) (Line: 242)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
- Deprecated function: Creation of dynamic property Drupal\mysql\Driver\Database\mysql\Select::$alterMetaData is deprecated in Drupal\Core\Database\Query\Select->addMetaData() (line 178 of core/lib/Drupal/Core/Database/Query/Select.php).
Drupal\Core\Database\Query\Select->addMetaData('entity_type', 'file') (Line: 115)
Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80)
Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640)
Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63)
Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', '27c857a1-7798-4b5a-9041-8e28cd68b77e') (Line: 124)
Drupal\editor\Plugin\Filter\EditorFileReference->process('Un interesante escenario es aquel que implica una tabla de datos que incluye la "ocupación" de unos ciertos recursos indicando la fecha de comienzo y la de finalización de la ocupación, teniendo como objetivo la visualización de una gráfica en la que se muestre el calendario y los días en los que cada recurso está ocupado o disponible.
Para resolver este escenario partimos de una tabla ("<em>Allocations</em>") en la que se muestra el recurso en cuestión (1, 2 o 3 en nuestro ejemplo), y las fechas de inicio y fin de la ocupación:
Partimos también de un calendario ("<em>Calendar</em>") que, en este ejemplo, está limitado a la quincena dentro de la cual se producen las ocupaciones de cada recurso:
Si generamos un gráfico a mano -usando Excel, por ejemplo-, la visualización de las ocupaciones de cada recurso tendría el siguiente aspecto:
El objetivo es llegar a una visualización semejante que se genere de forma automática.
Obsérvese que si cruzamos la tabla "Allocations" (que incluye los períodos en los que cada recurso está reservado) y el calendario mediante la función <a href="/dax/function/generate">GENERATE</a>, por ejemplo (también valdría la función <a href="/dax/function/crossjoin">CROSSJOIN</a> pues, en este caso, no estamos haciendo uso del contexto de fila generado por las filas de la primera tabla), tendremos todas las posibles combinaciones entre las filas de ambas:
Table =
GENERATE(
Allocations;
'Calendar'
)
Y de esta tabla, es sencillo quedarnos solo con los días en los que el recurso está reservado si seleccionamos apenas aquellas filas en las que el campo <em>Date </em>sea mayor o igual a <em>Start </em>y menor o igual a <em>End</em>, para lo que recurrimos a la función <a href="/dax/function/filter">FILTER</a>:
Table =
FILTER(
GENERATE(
Allocations;
'Calendar'
);
'Calendar'[Date] >= Allocations[Start] && 'Calendar'[Date] <= Allocations[End]
)
En este punto podríamos obviar los campos <em>Start </em>y <em>End</em>, que ya no aportan nada, para lo que podemos recurrir a la función <a href="/dax/function/selectcolumns">SELECTCOLUMNS</a> que nos permite escoger qué campos queremos seleccionar:
Table =
SELECTCOLUMNS(
FILTER(
GENERATE(
Allocations;
'Calendar'
);
'Calendar'[Date] >= Allocations[Start] && 'Calendar'[Date] <= Allocations[End]
);
"Id"; Allocations[Id];
"Resource"; Allocations[Resource];
"Date"; 'Calendar'[Date]
)
Para visualizar el resultado vamos a recurrir a la visualización "<em>as Timeline</em>" descargable desde el marketplace. Una vez llevada al lienzo su configuración es la siguiente:
Y la visualización queda de la siguiente forma:
Podemos comparar el resultado con el esquema realizado a mano:
También habríamos podido aprovechar el contexto de fila creado por la función GENERATE para incluir el filtro dentro de la propia función, de la siguiente manera:
Table =
SELECTCOLUMNS(
GENERATE(
Allocations;
FILTER(
'Calendar';
'Calendar'[Date] >= Allocations[Start] && 'Calendar'[Date] <= Allocations[End]
)
);
"Id"; Allocations[Id];
"Resource"; Allocations[Resource];
"Date"; 'Calendar'[Date]
)
', 'es') (Line: 118)
Drupal\filter\Element\ProcessedText::preRenderText(Array)
call_user_func_array(Array, Array) (Line: 101)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88)
__TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 46)
__TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 43)
__TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110)
__TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, ) (Line: 242)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
- Deprecated function: Creation of dynamic property Drupal\mysql\Driver\Database\mysql\Select::$alterTags is deprecated in Drupal\Core\Database\Query\Select->addTag() (line 149 of core/lib/Drupal/Core/Database/Query/Select.php).
Drupal\Core\Database\Query\Select->addTag('entity_query') (Line: 147)
Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80)
Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640)
Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63)
Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', '27c857a1-7798-4b5a-9041-8e28cd68b77e') (Line: 124)
Drupal\editor\Plugin\Filter\EditorFileReference->process('Un interesante escenario es aquel que implica una tabla de datos que incluye la "ocupación" de unos ciertos recursos indicando la fecha de comienzo y la de finalización de la ocupación, teniendo como objetivo la visualización de una gráfica en la que se muestre el calendario y los días en los que cada recurso está ocupado o disponible.
Para resolver este escenario partimos de una tabla ("<em>Allocations</em>") en la que se muestra el recurso en cuestión (1, 2 o 3 en nuestro ejemplo), y las fechas de inicio y fin de la ocupación:
Partimos también de un calendario ("<em>Calendar</em>") que, en este ejemplo, está limitado a la quincena dentro de la cual se producen las ocupaciones de cada recurso:
Si generamos un gráfico a mano -usando Excel, por ejemplo-, la visualización de las ocupaciones de cada recurso tendría el siguiente aspecto:
El objetivo es llegar a una visualización semejante que se genere de forma automática.
Obsérvese que si cruzamos la tabla "Allocations" (que incluye los períodos en los que cada recurso está reservado) y el calendario mediante la función <a href="/dax/function/generate">GENERATE</a>, por ejemplo (también valdría la función <a href="/dax/function/crossjoin">CROSSJOIN</a> pues, en este caso, no estamos haciendo uso del contexto de fila generado por las filas de la primera tabla), tendremos todas las posibles combinaciones entre las filas de ambas:
Table =
GENERATE(
Allocations;
'Calendar'
)
Y de esta tabla, es sencillo quedarnos solo con los días en los que el recurso está reservado si seleccionamos apenas aquellas filas en las que el campo <em>Date </em>sea mayor o igual a <em>Start </em>y menor o igual a <em>End</em>, para lo que recurrimos a la función <a href="/dax/function/filter">FILTER</a>:
Table =
FILTER(
GENERATE(
Allocations;
'Calendar'
);
'Calendar'[Date] >= Allocations[Start] && 'Calendar'[Date] <= Allocations[End]
)
En este punto podríamos obviar los campos <em>Start </em>y <em>End</em>, que ya no aportan nada, para lo que podemos recurrir a la función <a href="/dax/function/selectcolumns">SELECTCOLUMNS</a> que nos permite escoger qué campos queremos seleccionar:
Table =
SELECTCOLUMNS(
FILTER(
GENERATE(
Allocations;
'Calendar'
);
'Calendar'[Date] >= Allocations[Start] && 'Calendar'[Date] <= Allocations[End]
);
"Id"; Allocations[Id];
"Resource"; Allocations[Resource];
"Date"; 'Calendar'[Date]
)
Para visualizar el resultado vamos a recurrir a la visualización "<em>as Timeline</em>" descargable desde el marketplace. Una vez llevada al lienzo su configuración es la siguiente:
Y la visualización queda de la siguiente forma:
Podemos comparar el resultado con el esquema realizado a mano:
También habríamos podido aprovechar el contexto de fila creado por la función GENERATE para incluir el filtro dentro de la propia función, de la siguiente manera:
Table =
SELECTCOLUMNS(
GENERATE(
Allocations;
FILTER(
'Calendar';
'Calendar'[Date] >= Allocations[Start] && 'Calendar'[Date] <= Allocations[End]
)
);
"Id"; Allocations[Id];
"Resource"; Allocations[Resource];
"Date"; 'Calendar'[Date]
)
', 'es') (Line: 118)
Drupal\filter\Element\ProcessedText::preRenderText(Array)
call_user_func_array(Array, Array) (Line: 101)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88)
__TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 46)
__TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 43)
__TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110)
__TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, ) (Line: 242)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
- Deprecated function: Creation of dynamic property Drupal\mysql\Driver\Database\mysql\Select::$alterMetaData is deprecated in Drupal\Core\Database\Query\Select->addMetaData() (line 178 of core/lib/Drupal/Core/Database/Query/Select.php).
Drupal\Core\Database\Query\Select->addMetaData('entity_type', 'file') (Line: 115)
Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80)
Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640)
Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63)
Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', 'e9a0d18c-4220-4395-972b-4e8c163c297f') (Line: 95)
Drupal\editor\Plugin\Filter\EditorFileReference->process('Un interesante escenario es aquel que implica una tabla de datos que incluye la "ocupación" de unos ciertos recursos indicando la fecha de comienzo y la de finalización de la ocupación, teniendo como objetivo la visualización de una gráfica en la que se muestre el calendario y los días en los que cada recurso está ocupado o disponible.
Para resolver este escenario partimos de una tabla ("<em>Allocations</em>") en la que se muestra el recurso en cuestión (1, 2 o 3 en nuestro ejemplo), y las fechas de inicio y fin de la ocupación:
Partimos también de un calendario ("<em>Calendar</em>") que, en este ejemplo, está limitado a la quincena dentro de la cual se producen las ocupaciones de cada recurso:
Si generamos un gráfico a mano -usando Excel, por ejemplo-, la visualización de las ocupaciones de cada recurso tendría el siguiente aspecto:
El objetivo es llegar a una visualización semejante que se genere de forma automática.
Obsérvese que si cruzamos la tabla "Allocations" (que incluye los períodos en los que cada recurso está reservado) y el calendario mediante la función <a href="/dax/function/generate">GENERATE</a>, por ejemplo (también valdría la función <a href="/dax/function/crossjoin">CROSSJOIN</a> pues, en este caso, no estamos haciendo uso del contexto de fila generado por las filas de la primera tabla), tendremos todas las posibles combinaciones entre las filas de ambas:
Table =
GENERATE(
Allocations;
'Calendar'
)
Y de esta tabla, es sencillo quedarnos solo con los días en los que el recurso está reservado si seleccionamos apenas aquellas filas en las que el campo <em>Date </em>sea mayor o igual a <em>Start </em>y menor o igual a <em>End</em>, para lo que recurrimos a la función <a href="/dax/function/filter">FILTER</a>:
Table =
FILTER(
GENERATE(
Allocations;
'Calendar'
);
'Calendar'[Date] >= Allocations[Start] && 'Calendar'[Date] <= Allocations[End]
)
En este punto podríamos obviar los campos <em>Start </em>y <em>End</em>, que ya no aportan nada, para lo que podemos recurrir a la función <a href="/dax/function/selectcolumns">SELECTCOLUMNS</a> que nos permite escoger qué campos queremos seleccionar:
Table =
SELECTCOLUMNS(
FILTER(
GENERATE(
Allocations;
'Calendar'
);
'Calendar'[Date] >= Allocations[Start] && 'Calendar'[Date] <= Allocations[End]
);
"Id"; Allocations[Id];
"Resource"; Allocations[Resource];
"Date"; 'Calendar'[Date]
)
Para visualizar el resultado vamos a recurrir a la visualización "<em>as Timeline</em>" descargable desde el marketplace. Una vez llevada al lienzo su configuración es la siguiente:
Y la visualización queda de la siguiente forma:
Podemos comparar el resultado con el esquema realizado a mano:
También habríamos podido aprovechar el contexto de fila creado por la función GENERATE para incluir el filtro dentro de la propia función, de la siguiente manera:
Table =
SELECTCOLUMNS(
GENERATE(
Allocations;
FILTER(
'Calendar';
'Calendar'[Date] >= Allocations[Start] && 'Calendar'[Date] <= Allocations[End]
)
);
"Id"; Allocations[Id];
"Resource"; Allocations[Resource];
"Date"; 'Calendar'[Date]
)
', 'es') (Line: 118)
Drupal\filter\Element\ProcessedText::preRenderText(Array)
call_user_func_array(Array, Array) (Line: 101)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88)
__TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 46)
__TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 43)
__TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110)
__TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, ) (Line: 242)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
- Deprecated function: Creation of dynamic property Drupal\mysql\Driver\Database\mysql\Select::$alterTags is deprecated in Drupal\Core\Database\Query\Select->addTag() (line 149 of core/lib/Drupal/Core/Database/Query/Select.php).
Drupal\Core\Database\Query\Select->addTag('entity_query') (Line: 147)
Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80)
Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640)
Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63)
Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', 'e9a0d18c-4220-4395-972b-4e8c163c297f') (Line: 95)
Drupal\editor\Plugin\Filter\EditorFileReference->process('Un interesante escenario es aquel que implica una tabla de datos que incluye la "ocupación" de unos ciertos recursos indicando la fecha de comienzo y la de finalización de la ocupación, teniendo como objetivo la visualización de una gráfica en la que se muestre el calendario y los días en los que cada recurso está ocupado o disponible.
Para resolver este escenario partimos de una tabla ("<em>Allocations</em>") en la que se muestra el recurso en cuestión (1, 2 o 3 en nuestro ejemplo), y las fechas de inicio y fin de la ocupación:
Partimos también de un calendario ("<em>Calendar</em>") que, en este ejemplo, está limitado a la quincena dentro de la cual se producen las ocupaciones de cada recurso:
Si generamos un gráfico a mano -usando Excel, por ejemplo-, la visualización de las ocupaciones de cada recurso tendría el siguiente aspecto:
El objetivo es llegar a una visualización semejante que se genere de forma automática.
Obsérvese que si cruzamos la tabla "Allocations" (que incluye los períodos en los que cada recurso está reservado) y el calendario mediante la función <a href="/dax/function/generate">GENERATE</a>, por ejemplo (también valdría la función <a href="/dax/function/crossjoin">CROSSJOIN</a> pues, en este caso, no estamos haciendo uso del contexto de fila generado por las filas de la primera tabla), tendremos todas las posibles combinaciones entre las filas de ambas:
Table =
GENERATE(
Allocations;
'Calendar'
)
Y de esta tabla, es sencillo quedarnos solo con los días en los que el recurso está reservado si seleccionamos apenas aquellas filas en las que el campo <em>Date </em>sea mayor o igual a <em>Start </em>y menor o igual a <em>End</em>, para lo que recurrimos a la función <a href="/dax/function/filter">FILTER</a>:
Table =
FILTER(
GENERATE(
Allocations;
'Calendar'
);
'Calendar'[Date] >= Allocations[Start] && 'Calendar'[Date] <= Allocations[End]
)
En este punto podríamos obviar los campos <em>Start </em>y <em>End</em>, que ya no aportan nada, para lo que podemos recurrir a la función <a href="/dax/function/selectcolumns">SELECTCOLUMNS</a> que nos permite escoger qué campos queremos seleccionar:
Table =
SELECTCOLUMNS(
FILTER(
GENERATE(
Allocations;
'Calendar'
);
'Calendar'[Date] >= Allocations[Start] && 'Calendar'[Date] <= Allocations[End]
);
"Id"; Allocations[Id];
"Resource"; Allocations[Resource];
"Date"; 'Calendar'[Date]
)
Para visualizar el resultado vamos a recurrir a la visualización "<em>as Timeline</em>" descargable desde el marketplace. Una vez llevada al lienzo su configuración es la siguiente:
Y la visualización queda de la siguiente forma:
Podemos comparar el resultado con el esquema realizado a mano:
También habríamos podido aprovechar el contexto de fila creado por la función GENERATE para incluir el filtro dentro de la propia función, de la siguiente manera:
Table =
SELECTCOLUMNS(
GENERATE(
Allocations;
FILTER(
'Calendar';
'Calendar'[Date] >= Allocations[Start] && 'Calendar'[Date] <= Allocations[End]
)
);
"Id"; Allocations[Id];
"Resource"; Allocations[Resource];
"Date"; 'Calendar'[Date]
)
', 'es') (Line: 118)
Drupal\filter\Element\ProcessedText::preRenderText(Array)
call_user_func_array(Array, Array) (Line: 101)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88)
__TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 46)
__TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 43)
__TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110)
__TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, ) (Line: 242)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
- Deprecated function: Creation of dynamic property Drupal\mysql\Driver\Database\mysql\Select::$alterMetaData is deprecated in Drupal\Core\Database\Query\Select->addMetaData() (line 178 of core/lib/Drupal/Core/Database/Query/Select.php).
Drupal\Core\Database\Query\Select->addMetaData('entity_type', 'file') (Line: 115)
Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80)
Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640)
Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63)
Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', '138cbae9-3a3d-4ed3-a00d-833f11d84aad') (Line: 95)
Drupal\editor\Plugin\Filter\EditorFileReference->process('En este escenario deseamos evaluar una métrica (por ejemplo, la suma de ventas) para el total de fechas previas a una dada. Partimos de una tabla de ventas ("<em>Ventas</em>") en la que se incluye una fecha ("<em>Fecha</em>") y un precio de venta ("<em>Precio final</em>"):
Adicionalmente tenemos una tabla conteniendo un calendario que, en este escenario, no está enlazado con la tabla de ventas para evitar un filtrado automático, y una visualización tipo "segmentación" en la que seleccionamos un período de interés a partir de las fechas del calendario:
Tenemos ya creada una medida que totaliza las ventas:
Ventas = SUM(Ventas[Precio final])
Como se ha comentado, el objetivo es sumar las ventas previas al período que seleccionemos en la segmentación (es decir, solo nos interesa la fecha más antigua del período seleccionado en la segmentación). En pseudo-código sería:
Recalcula la medida "Ventas"
Para las fechas anteriores a la fecha mínima de la segmentación
Como la segmentación está filtrando el calendario (pues esta visualización se ha generado a partir de él), lo anterior sería equivalente a:
Recalcula la medida "Ventas"
Para las fechas anteriores a la fecha mínima del calendario
Este esquema encaja con la estructura de la función <a href="/dax/function/calculate">CALCULATE</a>, añadiendo como filtro el contexto dado por la segunda condición:
CALCULATE(
Medida de Ventas;
Tabla de ventas tal que Ventas[Fecha] < Fecha mínima del calendario
)
Para concretar el filtrado vamos a recurrir a la función <a href="/dax/function/filter">FILTER</a>, que acepta como primer argumento una tabla y como segundo argumento un criterio de filtrado. En este caso la tabla a filtrar es la tabla de ventas y el criterio, que la fecha de venta sea menor que la menor fecha del calendario. El código quedaría de la siguiente forma:
Ventas previas = CALCULATE(
[Ventas];
FILTER(
Ventas;
Ventas[Fecha] < MIN(Calendario[Date])
)
)
Probemos el código seleccionando una fecha en el segmentador que incluya solo un par de ventas:
', 'es') (Line: 118)
Drupal\filter\Element\ProcessedText::preRenderText(Array)
call_user_func_array(Array, Array) (Line: 101)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88)
__TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 46)
__TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 43)
__TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110)
__TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, ) (Line: 242)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
- Deprecated function: Creation of dynamic property Drupal\mysql\Driver\Database\mysql\Select::$alterTags is deprecated in Drupal\Core\Database\Query\Select->addTag() (line 149 of core/lib/Drupal/Core/Database/Query/Select.php).
Drupal\Core\Database\Query\Select->addTag('entity_query') (Line: 147)
Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80)
Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640)
Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63)
Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', '138cbae9-3a3d-4ed3-a00d-833f11d84aad') (Line: 95)
Drupal\editor\Plugin\Filter\EditorFileReference->process('En este escenario deseamos evaluar una métrica (por ejemplo, la suma de ventas) para el total de fechas previas a una dada. Partimos de una tabla de ventas ("<em>Ventas</em>") en la que se incluye una fecha ("<em>Fecha</em>") y un precio de venta ("<em>Precio final</em>"):
Adicionalmente tenemos una tabla conteniendo un calendario que, en este escenario, no está enlazado con la tabla de ventas para evitar un filtrado automático, y una visualización tipo "segmentación" en la que seleccionamos un período de interés a partir de las fechas del calendario:
Tenemos ya creada una medida que totaliza las ventas:
Ventas = SUM(Ventas[Precio final])
Como se ha comentado, el objetivo es sumar las ventas previas al período que seleccionemos en la segmentación (es decir, solo nos interesa la fecha más antigua del período seleccionado en la segmentación). En pseudo-código sería:
Recalcula la medida "Ventas"
Para las fechas anteriores a la fecha mínima de la segmentación
Como la segmentación está filtrando el calendario (pues esta visualización se ha generado a partir de él), lo anterior sería equivalente a:
Recalcula la medida "Ventas"
Para las fechas anteriores a la fecha mínima del calendario
Este esquema encaja con la estructura de la función <a href="/dax/function/calculate">CALCULATE</a>, añadiendo como filtro el contexto dado por la segunda condición:
CALCULATE(
Medida de Ventas;
Tabla de ventas tal que Ventas[Fecha] < Fecha mínima del calendario
)
Para concretar el filtrado vamos a recurrir a la función <a href="/dax/function/filter">FILTER</a>, que acepta como primer argumento una tabla y como segundo argumento un criterio de filtrado. En este caso la tabla a filtrar es la tabla de ventas y el criterio, que la fecha de venta sea menor que la menor fecha del calendario. El código quedaría de la siguiente forma:
Ventas previas = CALCULATE(
[Ventas];
FILTER(
Ventas;
Ventas[Fecha] < MIN(Calendario[Date])
)
)
Probemos el código seleccionando una fecha en el segmentador que incluya solo un par de ventas:
', 'es') (Line: 118)
Drupal\filter\Element\ProcessedText::preRenderText(Array)
call_user_func_array(Array, Array) (Line: 101)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88)
__TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 46)
__TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 43)
__TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110)
__TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, ) (Line: 242)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
- Deprecated function: Creation of dynamic property Drupal\mysql\Driver\Database\mysql\Select::$alterTags is deprecated in Drupal\Core\Database\Query\Select->addTag() (line 149 of core/lib/Drupal/Core/Database/Query/Select.php).
Drupal\Core\Database\Query\Select->addTag('file_load_multiple') (Line: 696)
Drupal\Core\Entity\Sql\SqlContentEntityStorage->buildQuery(Array) (Line: 422)
Drupal\Core\Entity\Sql\SqlContentEntityStorage->getFromStorage(Array) (Line: 393)
Drupal\Core\Entity\Sql\SqlContentEntityStorage->doLoadMultiple(Array) (Line: 346)
Drupal\Core\Entity\EntityStorageBase->loadMultiple(Array) (Line: 641)
Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63)
Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', '138cbae9-3a3d-4ed3-a00d-833f11d84aad') (Line: 95)
Drupal\editor\Plugin\Filter\EditorFileReference->process('En este escenario deseamos evaluar una métrica (por ejemplo, la suma de ventas) para el total de fechas previas a una dada. Partimos de una tabla de ventas ("<em>Ventas</em>") en la que se incluye una fecha ("<em>Fecha</em>") y un precio de venta ("<em>Precio final</em>"):
Adicionalmente tenemos una tabla conteniendo un calendario que, en este escenario, no está enlazado con la tabla de ventas para evitar un filtrado automático, y una visualización tipo "segmentación" en la que seleccionamos un período de interés a partir de las fechas del calendario:
Tenemos ya creada una medida que totaliza las ventas:
Ventas = SUM(Ventas[Precio final])
Como se ha comentado, el objetivo es sumar las ventas previas al período que seleccionemos en la segmentación (es decir, solo nos interesa la fecha más antigua del período seleccionado en la segmentación). En pseudo-código sería:
Recalcula la medida "Ventas"
Para las fechas anteriores a la fecha mínima de la segmentación
Como la segmentación está filtrando el calendario (pues esta visualización se ha generado a partir de él), lo anterior sería equivalente a:
Recalcula la medida "Ventas"
Para las fechas anteriores a la fecha mínima del calendario
Este esquema encaja con la estructura de la función <a href="/dax/function/calculate">CALCULATE</a>, añadiendo como filtro el contexto dado por la segunda condición:
CALCULATE(
Medida de Ventas;
Tabla de ventas tal que Ventas[Fecha] < Fecha mínima del calendario
)
Para concretar el filtrado vamos a recurrir a la función <a href="/dax/function/filter">FILTER</a>, que acepta como primer argumento una tabla y como segundo argumento un criterio de filtrado. En este caso la tabla a filtrar es la tabla de ventas y el criterio, que la fecha de venta sea menor que la menor fecha del calendario. El código quedaría de la siguiente forma:
Ventas previas = CALCULATE(
[Ventas];
FILTER(
Ventas;
Ventas[Fecha] < MIN(Calendario[Date])
)
)
Probemos el código seleccionando una fecha en el segmentador que incluya solo un par de ventas:
', 'es') (Line: 118)
Drupal\filter\Element\ProcessedText::preRenderText(Array)
call_user_func_array(Array, Array) (Line: 101)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88)
__TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 46)
__TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 43)
__TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110)
__TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, ) (Line: 242)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
- Deprecated function: Creation of dynamic property Drupal\mysql\Driver\Database\mysql\Select::$alterMetaData is deprecated in Drupal\Core\Database\Query\Select->addMetaData() (line 178 of core/lib/Drupal/Core/Database/Query/Select.php).
Drupal\Core\Database\Query\Select->addMetaData('entity_type', 'file') (Line: 115)
Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80)
Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640)
Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63)
Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', '138cbae9-3a3d-4ed3-a00d-833f11d84aad') (Line: 124)
Drupal\editor\Plugin\Filter\EditorFileReference->process('En este escenario deseamos evaluar una métrica (por ejemplo, la suma de ventas) para el total de fechas previas a una dada. Partimos de una tabla de ventas ("<em>Ventas</em>") en la que se incluye una fecha ("<em>Fecha</em>") y un precio de venta ("<em>Precio final</em>"):
Adicionalmente tenemos una tabla conteniendo un calendario que, en este escenario, no está enlazado con la tabla de ventas para evitar un filtrado automático, y una visualización tipo "segmentación" en la que seleccionamos un período de interés a partir de las fechas del calendario:
Tenemos ya creada una medida que totaliza las ventas:
Ventas = SUM(Ventas[Precio final])
Como se ha comentado, el objetivo es sumar las ventas previas al período que seleccionemos en la segmentación (es decir, solo nos interesa la fecha más antigua del período seleccionado en la segmentación). En pseudo-código sería:
Recalcula la medida "Ventas"
Para las fechas anteriores a la fecha mínima de la segmentación
Como la segmentación está filtrando el calendario (pues esta visualización se ha generado a partir de él), lo anterior sería equivalente a:
Recalcula la medida "Ventas"
Para las fechas anteriores a la fecha mínima del calendario
Este esquema encaja con la estructura de la función <a href="/dax/function/calculate">CALCULATE</a>, añadiendo como filtro el contexto dado por la segunda condición:
CALCULATE(
Medida de Ventas;
Tabla de ventas tal que Ventas[Fecha] < Fecha mínima del calendario
)
Para concretar el filtrado vamos a recurrir a la función <a href="/dax/function/filter">FILTER</a>, que acepta como primer argumento una tabla y como segundo argumento un criterio de filtrado. En este caso la tabla a filtrar es la tabla de ventas y el criterio, que la fecha de venta sea menor que la menor fecha del calendario. El código quedaría de la siguiente forma:
Ventas previas = CALCULATE(
[Ventas];
FILTER(
Ventas;
Ventas[Fecha] < MIN(Calendario[Date])
)
)
Probemos el código seleccionando una fecha en el segmentador que incluya solo un par de ventas:
', 'es') (Line: 118)
Drupal\filter\Element\ProcessedText::preRenderText(Array)
call_user_func_array(Array, Array) (Line: 101)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88)
__TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 46)
__TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 43)
__TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110)
__TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, ) (Line: 242)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
- Deprecated function: Creation of dynamic property Drupal\mysql\Driver\Database\mysql\Select::$alterTags is deprecated in Drupal\Core\Database\Query\Select->addTag() (line 149 of core/lib/Drupal/Core/Database/Query/Select.php).
Drupal\Core\Database\Query\Select->addTag('entity_query') (Line: 147)
Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80)
Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640)
Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63)
Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', '138cbae9-3a3d-4ed3-a00d-833f11d84aad') (Line: 124)
Drupal\editor\Plugin\Filter\EditorFileReference->process('En este escenario deseamos evaluar una métrica (por ejemplo, la suma de ventas) para el total de fechas previas a una dada. Partimos de una tabla de ventas ("<em>Ventas</em>") en la que se incluye una fecha ("<em>Fecha</em>") y un precio de venta ("<em>Precio final</em>"):
Adicionalmente tenemos una tabla conteniendo un calendario que, en este escenario, no está enlazado con la tabla de ventas para evitar un filtrado automático, y una visualización tipo "segmentación" en la que seleccionamos un período de interés a partir de las fechas del calendario:
Tenemos ya creada una medida que totaliza las ventas:
Ventas = SUM(Ventas[Precio final])
Como se ha comentado, el objetivo es sumar las ventas previas al período que seleccionemos en la segmentación (es decir, solo nos interesa la fecha más antigua del período seleccionado en la segmentación). En pseudo-código sería:
Recalcula la medida "Ventas"
Para las fechas anteriores a la fecha mínima de la segmentación
Como la segmentación está filtrando el calendario (pues esta visualización se ha generado a partir de él), lo anterior sería equivalente a:
Recalcula la medida "Ventas"
Para las fechas anteriores a la fecha mínima del calendario
Este esquema encaja con la estructura de la función <a href="/dax/function/calculate">CALCULATE</a>, añadiendo como filtro el contexto dado por la segunda condición:
CALCULATE(
Medida de Ventas;
Tabla de ventas tal que Ventas[Fecha] < Fecha mínima del calendario
)
Para concretar el filtrado vamos a recurrir a la función <a href="/dax/function/filter">FILTER</a>, que acepta como primer argumento una tabla y como segundo argumento un criterio de filtrado. En este caso la tabla a filtrar es la tabla de ventas y el criterio, que la fecha de venta sea menor que la menor fecha del calendario. El código quedaría de la siguiente forma:
Ventas previas = CALCULATE(
[Ventas];
FILTER(
Ventas;
Ventas[Fecha] < MIN(Calendario[Date])
)
)
Probemos el código seleccionando una fecha en el segmentador que incluya solo un par de ventas:
', 'es') (Line: 118)
Drupal\filter\Element\ProcessedText::preRenderText(Array)
call_user_func_array(Array, Array) (Line: 101)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88)
__TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 46)
__TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 43)
__TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110)
__TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, ) (Line: 242)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
- Deprecated function: Creation of dynamic property Drupal\mysql\Driver\Database\mysql\Select::$alterMetaData is deprecated in Drupal\Core\Database\Query\Select->addMetaData() (line 178 of core/lib/Drupal/Core/Database/Query/Select.php).
Drupal\Core\Database\Query\Select->addMetaData('entity_type', 'file') (Line: 115)
Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80)
Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640)
Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63)
Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', '7eb8ed33-87f4-4ba9-a994-aa7da330abeb') (Line: 95)
Drupal\editor\Plugin\Filter\EditorFileReference->process('En este escenario deseamos evaluar una métrica (por ejemplo, la suma de ventas) para el total de fechas previas a una dada. Partimos de una tabla de ventas ("<em>Ventas</em>") en la que se incluye una fecha ("<em>Fecha</em>") y un precio de venta ("<em>Precio final</em>"):
Adicionalmente tenemos una tabla conteniendo un calendario que, en este escenario, no está enlazado con la tabla de ventas para evitar un filtrado automático, y una visualización tipo "segmentación" en la que seleccionamos un período de interés a partir de las fechas del calendario:
Tenemos ya creada una medida que totaliza las ventas:
Ventas = SUM(Ventas[Precio final])
Como se ha comentado, el objetivo es sumar las ventas previas al período que seleccionemos en la segmentación (es decir, solo nos interesa la fecha más antigua del período seleccionado en la segmentación). En pseudo-código sería:
Recalcula la medida "Ventas"
Para las fechas anteriores a la fecha mínima de la segmentación
Como la segmentación está filtrando el calendario (pues esta visualización se ha generado a partir de él), lo anterior sería equivalente a:
Recalcula la medida "Ventas"
Para las fechas anteriores a la fecha mínima del calendario
Este esquema encaja con la estructura de la función <a href="/dax/function/calculate">CALCULATE</a>, añadiendo como filtro el contexto dado por la segunda condición:
CALCULATE(
Medida de Ventas;
Tabla de ventas tal que Ventas[Fecha] < Fecha mínima del calendario
)
Para concretar el filtrado vamos a recurrir a la función <a href="/dax/function/filter">FILTER</a>, que acepta como primer argumento una tabla y como segundo argumento un criterio de filtrado. En este caso la tabla a filtrar es la tabla de ventas y el criterio, que la fecha de venta sea menor que la menor fecha del calendario. El código quedaría de la siguiente forma:
Ventas previas = CALCULATE(
[Ventas];
FILTER(
Ventas;
Ventas[Fecha] < MIN(Calendario[Date])
)
)
Probemos el código seleccionando una fecha en el segmentador que incluya solo un par de ventas:
', 'es') (Line: 118)
Drupal\filter\Element\ProcessedText::preRenderText(Array)
call_user_func_array(Array, Array) (Line: 101)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88)
__TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 46)
__TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 43)
__TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110)
__TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, ) (Line: 242)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
- Deprecated function: Creation of dynamic property Drupal\mysql\Driver\Database\mysql\Select::$alterTags is deprecated in Drupal\Core\Database\Query\Select->addTag() (line 149 of core/lib/Drupal/Core/Database/Query/Select.php).
Drupal\Core\Database\Query\Select->addTag('entity_query') (Line: 147)
Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80)
Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640)
Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63)
Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', '7eb8ed33-87f4-4ba9-a994-aa7da330abeb') (Line: 95)
Drupal\editor\Plugin\Filter\EditorFileReference->process('En este escenario deseamos evaluar una métrica (por ejemplo, la suma de ventas) para el total de fechas previas a una dada. Partimos de una tabla de ventas ("<em>Ventas</em>") en la que se incluye una fecha ("<em>Fecha</em>") y un precio de venta ("<em>Precio final</em>"):
Adicionalmente tenemos una tabla conteniendo un calendario que, en este escenario, no está enlazado con la tabla de ventas para evitar un filtrado automático, y una visualización tipo "segmentación" en la que seleccionamos un período de interés a partir de las fechas del calendario:
Tenemos ya creada una medida que totaliza las ventas:
Ventas = SUM(Ventas[Precio final])
Como se ha comentado, el objetivo es sumar las ventas previas al período que seleccionemos en la segmentación (es decir, solo nos interesa la fecha más antigua del período seleccionado en la segmentación). En pseudo-código sería:
Recalcula la medida "Ventas"
Para las fechas anteriores a la fecha mínima de la segmentación
Como la segmentación está filtrando el calendario (pues esta visualización se ha generado a partir de él), lo anterior sería equivalente a:
Recalcula la medida "Ventas"
Para las fechas anteriores a la fecha mínima del calendario
Este esquema encaja con la estructura de la función <a href="/dax/function/calculate">CALCULATE</a>, añadiendo como filtro el contexto dado por la segunda condición:
CALCULATE(
Medida de Ventas;
Tabla de ventas tal que Ventas[Fecha] < Fecha mínima del calendario
)
Para concretar el filtrado vamos a recurrir a la función <a href="/dax/function/filter">FILTER</a>, que acepta como primer argumento una tabla y como segundo argumento un criterio de filtrado. En este caso la tabla a filtrar es la tabla de ventas y el criterio, que la fecha de venta sea menor que la menor fecha del calendario. El código quedaría de la siguiente forma:
Ventas previas = CALCULATE(
[Ventas];
FILTER(
Ventas;
Ventas[Fecha] < MIN(Calendario[Date])
)
)
Probemos el código seleccionando una fecha en el segmentador que incluya solo un par de ventas:
', 'es') (Line: 118)
Drupal\filter\Element\ProcessedText::preRenderText(Array)
call_user_func_array(Array, Array) (Line: 101)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88)
__TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 46)
__TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 43)
__TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110)
__TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, ) (Line: 242)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
- Deprecated function: Creation of dynamic property Drupal\mysql\Driver\Database\mysql\Select::$alterTags is deprecated in Drupal\Core\Database\Query\Select->addTag() (line 149 of core/lib/Drupal/Core/Database/Query/Select.php).
Drupal\Core\Database\Query\Select->addTag('file_load_multiple') (Line: 696)
Drupal\Core\Entity\Sql\SqlContentEntityStorage->buildQuery(Array) (Line: 422)
Drupal\Core\Entity\Sql\SqlContentEntityStorage->getFromStorage(Array) (Line: 393)
Drupal\Core\Entity\Sql\SqlContentEntityStorage->doLoadMultiple(Array) (Line: 346)
Drupal\Core\Entity\EntityStorageBase->loadMultiple(Array) (Line: 641)
Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63)
Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', '7eb8ed33-87f4-4ba9-a994-aa7da330abeb') (Line: 95)
Drupal\editor\Plugin\Filter\EditorFileReference->process('En este escenario deseamos evaluar una métrica (por ejemplo, la suma de ventas) para el total de fechas previas a una dada. Partimos de una tabla de ventas ("<em>Ventas</em>") en la que se incluye una fecha ("<em>Fecha</em>") y un precio de venta ("<em>Precio final</em>"):
Adicionalmente tenemos una tabla conteniendo un calendario que, en este escenario, no está enlazado con la tabla de ventas para evitar un filtrado automático, y una visualización tipo "segmentación" en la que seleccionamos un período de interés a partir de las fechas del calendario:
Tenemos ya creada una medida que totaliza las ventas:
Ventas = SUM(Ventas[Precio final])
Como se ha comentado, el objetivo es sumar las ventas previas al período que seleccionemos en la segmentación (es decir, solo nos interesa la fecha más antigua del período seleccionado en la segmentación). En pseudo-código sería:
Recalcula la medida "Ventas"
Para las fechas anteriores a la fecha mínima de la segmentación
Como la segmentación está filtrando el calendario (pues esta visualización se ha generado a partir de él), lo anterior sería equivalente a:
Recalcula la medida "Ventas"
Para las fechas anteriores a la fecha mínima del calendario
Este esquema encaja con la estructura de la función <a href="/dax/function/calculate">CALCULATE</a>, añadiendo como filtro el contexto dado por la segunda condición:
CALCULATE(
Medida de Ventas;
Tabla de ventas tal que Ventas[Fecha] < Fecha mínima del calendario
)
Para concretar el filtrado vamos a recurrir a la función <a href="/dax/function/filter">FILTER</a>, que acepta como primer argumento una tabla y como segundo argumento un criterio de filtrado. En este caso la tabla a filtrar es la tabla de ventas y el criterio, que la fecha de venta sea menor que la menor fecha del calendario. El código quedaría de la siguiente forma:
Ventas previas = CALCULATE(
[Ventas];
FILTER(
Ventas;
Ventas[Fecha] < MIN(Calendario[Date])
)
)
Probemos el código seleccionando una fecha en el segmentador que incluya solo un par de ventas:
', 'es') (Line: 118)
Drupal\filter\Element\ProcessedText::preRenderText(Array)
call_user_func_array(Array, Array) (Line: 101)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88)
__TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 46)
__TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 43)
__TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110)
__TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, ) (Line: 242)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
- Deprecated function: Creation of dynamic property Drupal\mysql\Driver\Database\mysql\Select::$alterMetaData is deprecated in Drupal\Core\Database\Query\Select->addMetaData() (line 178 of core/lib/Drupal/Core/Database/Query/Select.php).
Drupal\Core\Database\Query\Select->addMetaData('entity_type', 'file') (Line: 115)
Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80)
Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640)
Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63)
Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', '7eb8ed33-87f4-4ba9-a994-aa7da330abeb') (Line: 124)
Drupal\editor\Plugin\Filter\EditorFileReference->process('En este escenario deseamos evaluar una métrica (por ejemplo, la suma de ventas) para el total de fechas previas a una dada. Partimos de una tabla de ventas ("<em>Ventas</em>") en la que se incluye una fecha ("<em>Fecha</em>") y un precio de venta ("<em>Precio final</em>"):
Adicionalmente tenemos una tabla conteniendo un calendario que, en este escenario, no está enlazado con la tabla de ventas para evitar un filtrado automático, y una visualización tipo "segmentación" en la que seleccionamos un período de interés a partir de las fechas del calendario:
Tenemos ya creada una medida que totaliza las ventas:
Ventas = SUM(Ventas[Precio final])
Como se ha comentado, el objetivo es sumar las ventas previas al período que seleccionemos en la segmentación (es decir, solo nos interesa la fecha más antigua del período seleccionado en la segmentación). En pseudo-código sería:
Recalcula la medida "Ventas"
Para las fechas anteriores a la fecha mínima de la segmentación
Como la segmentación está filtrando el calendario (pues esta visualización se ha generado a partir de él), lo anterior sería equivalente a:
Recalcula la medida "Ventas"
Para las fechas anteriores a la fecha mínima del calendario
Este esquema encaja con la estructura de la función <a href="/dax/function/calculate">CALCULATE</a>, añadiendo como filtro el contexto dado por la segunda condición:
CALCULATE(
Medida de Ventas;
Tabla de ventas tal que Ventas[Fecha] < Fecha mínima del calendario
)
Para concretar el filtrado vamos a recurrir a la función <a href="/dax/function/filter">FILTER</a>, que acepta como primer argumento una tabla y como segundo argumento un criterio de filtrado. En este caso la tabla a filtrar es la tabla de ventas y el criterio, que la fecha de venta sea menor que la menor fecha del calendario. El código quedaría de la siguiente forma:
Ventas previas = CALCULATE(
[Ventas];
FILTER(
Ventas;
Ventas[Fecha] < MIN(Calendario[Date])
)
)
Probemos el código seleccionando una fecha en el segmentador que incluya solo un par de ventas:
', 'es') (Line: 118)
Drupal\filter\Element\ProcessedText::preRenderText(Array)
call_user_func_array(Array, Array) (Line: 101)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88)
__TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 46)
__TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 43)
__TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110)
__TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, ) (Line: 242)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
- Deprecated function: Creation of dynamic property Drupal\mysql\Driver\Database\mysql\Select::$alterTags is deprecated in Drupal\Core\Database\Query\Select->addTag() (line 149 of core/lib/Drupal/Core/Database/Query/Select.php).
Drupal\Core\Database\Query\Select->addTag('entity_query') (Line: 147)
Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80)
Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640)
Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63)
Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', '7eb8ed33-87f4-4ba9-a994-aa7da330abeb') (Line: 124)
Drupal\editor\Plugin\Filter\EditorFileReference->process('En este escenario deseamos evaluar una métrica (por ejemplo, la suma de ventas) para el total de fechas previas a una dada. Partimos de una tabla de ventas ("<em>Ventas</em>") en la que se incluye una fecha ("<em>Fecha</em>") y un precio de venta ("<em>Precio final</em>"):
Adicionalmente tenemos una tabla conteniendo un calendario que, en este escenario, no está enlazado con la tabla de ventas para evitar un filtrado automático, y una visualización tipo "segmentación" en la que seleccionamos un período de interés a partir de las fechas del calendario:
Tenemos ya creada una medida que totaliza las ventas:
Ventas = SUM(Ventas[Precio final])
Como se ha comentado, el objetivo es sumar las ventas previas al período que seleccionemos en la segmentación (es decir, solo nos interesa la fecha más antigua del período seleccionado en la segmentación). En pseudo-código sería:
Recalcula la medida "Ventas"
Para las fechas anteriores a la fecha mínima de la segmentación
Como la segmentación está filtrando el calendario (pues esta visualización se ha generado a partir de él), lo anterior sería equivalente a:
Recalcula la medida "Ventas"
Para las fechas anteriores a la fecha mínima del calendario
Este esquema encaja con la estructura de la función <a href="/dax/function/calculate">CALCULATE</a>, añadiendo como filtro el contexto dado por la segunda condición:
CALCULATE(
Medida de Ventas;
Tabla de ventas tal que Ventas[Fecha] < Fecha mínima del calendario
)
Para concretar el filtrado vamos a recurrir a la función <a href="/dax/function/filter">FILTER</a>, que acepta como primer argumento una tabla y como segundo argumento un criterio de filtrado. En este caso la tabla a filtrar es la tabla de ventas y el criterio, que la fecha de venta sea menor que la menor fecha del calendario. El código quedaría de la siguiente forma:
Ventas previas = CALCULATE(
[Ventas];
FILTER(
Ventas;
Ventas[Fecha] < MIN(Calendario[Date])
)
)
Probemos el código seleccionando una fecha en el segmentador que incluya solo un par de ventas:
', 'es') (Line: 118)
Drupal\filter\Element\ProcessedText::preRenderText(Array)
call_user_func_array(Array, Array) (Line: 101)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88)
__TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 46)
__TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 43)
__TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110)
__TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, ) (Line: 242)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
- Deprecated function: Creation of dynamic property Drupal\mysql\Driver\Database\mysql\Select::$alterMetaData is deprecated in Drupal\Core\Database\Query\Select->addMetaData() (line 178 of core/lib/Drupal/Core/Database/Query/Select.php).
Drupal\Core\Database\Query\Select->addMetaData('entity_type', 'file') (Line: 115)
Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80)
Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640)
Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63)
Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', '889838af-b5e8-477b-9185-7f190ec4e0c2') (Line: 95)
Drupal\editor\Plugin\Filter\EditorFileReference->process('En este escenario deseamos evaluar una métrica (por ejemplo, la suma de ventas) para el total de fechas previas a una dada. Partimos de una tabla de ventas ("<em>Ventas</em>") en la que se incluye una fecha ("<em>Fecha</em>") y un precio de venta ("<em>Precio final</em>"):
Adicionalmente tenemos una tabla conteniendo un calendario que, en este escenario, no está enlazado con la tabla de ventas para evitar un filtrado automático, y una visualización tipo "segmentación" en la que seleccionamos un período de interés a partir de las fechas del calendario:
Tenemos ya creada una medida que totaliza las ventas:
Ventas = SUM(Ventas[Precio final])
Como se ha comentado, el objetivo es sumar las ventas previas al período que seleccionemos en la segmentación (es decir, solo nos interesa la fecha más antigua del período seleccionado en la segmentación). En pseudo-código sería:
Recalcula la medida "Ventas"
Para las fechas anteriores a la fecha mínima de la segmentación
Como la segmentación está filtrando el calendario (pues esta visualización se ha generado a partir de él), lo anterior sería equivalente a:
Recalcula la medida "Ventas"
Para las fechas anteriores a la fecha mínima del calendario
Este esquema encaja con la estructura de la función <a href="/dax/function/calculate">CALCULATE</a>, añadiendo como filtro el contexto dado por la segunda condición:
CALCULATE(
Medida de Ventas;
Tabla de ventas tal que Ventas[Fecha] < Fecha mínima del calendario
)
Para concretar el filtrado vamos a recurrir a la función <a href="/dax/function/filter">FILTER</a>, que acepta como primer argumento una tabla y como segundo argumento un criterio de filtrado. En este caso la tabla a filtrar es la tabla de ventas y el criterio, que la fecha de venta sea menor que la menor fecha del calendario. El código quedaría de la siguiente forma:
Ventas previas = CALCULATE(
[Ventas];
FILTER(
Ventas;
Ventas[Fecha] < MIN(Calendario[Date])
)
)
Probemos el código seleccionando una fecha en el segmentador que incluya solo un par de ventas:
', 'es') (Line: 118)
Drupal\filter\Element\ProcessedText::preRenderText(Array)
call_user_func_array(Array, Array) (Line: 101)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88)
__TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 46)
__TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 43)
__TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110)
__TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, ) (Line: 242)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
- Deprecated function: Creation of dynamic property Drupal\mysql\Driver\Database\mysql\Select::$alterTags is deprecated in Drupal\Core\Database\Query\Select->addTag() (line 149 of core/lib/Drupal/Core/Database/Query/Select.php).
Drupal\Core\Database\Query\Select->addTag('entity_query') (Line: 147)
Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80)
Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640)
Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63)
Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', '889838af-b5e8-477b-9185-7f190ec4e0c2') (Line: 95)
Drupal\editor\Plugin\Filter\EditorFileReference->process('En este escenario deseamos evaluar una métrica (por ejemplo, la suma de ventas) para el total de fechas previas a una dada. Partimos de una tabla de ventas ("<em>Ventas</em>") en la que se incluye una fecha ("<em>Fecha</em>") y un precio de venta ("<em>Precio final</em>"):
Adicionalmente tenemos una tabla conteniendo un calendario que, en este escenario, no está enlazado con la tabla de ventas para evitar un filtrado automático, y una visualización tipo "segmentación" en la que seleccionamos un período de interés a partir de las fechas del calendario:
Tenemos ya creada una medida que totaliza las ventas:
Ventas = SUM(Ventas[Precio final])
Como se ha comentado, el objetivo es sumar las ventas previas al período que seleccionemos en la segmentación (es decir, solo nos interesa la fecha más antigua del período seleccionado en la segmentación). En pseudo-código sería:
Recalcula la medida "Ventas"
Para las fechas anteriores a la fecha mínima de la segmentación
Como la segmentación está filtrando el calendario (pues esta visualización se ha generado a partir de él), lo anterior sería equivalente a:
Recalcula la medida "Ventas"
Para las fechas anteriores a la fecha mínima del calendario
Este esquema encaja con la estructura de la función <a href="/dax/function/calculate">CALCULATE</a>, añadiendo como filtro el contexto dado por la segunda condición:
CALCULATE(
Medida de Ventas;
Tabla de ventas tal que Ventas[Fecha] < Fecha mínima del calendario
)
Para concretar el filtrado vamos a recurrir a la función <a href="/dax/function/filter">FILTER</a>, que acepta como primer argumento una tabla y como segundo argumento un criterio de filtrado. En este caso la tabla a filtrar es la tabla de ventas y el criterio, que la fecha de venta sea menor que la menor fecha del calendario. El código quedaría de la siguiente forma:
Ventas previas = CALCULATE(
[Ventas];
FILTER(
Ventas;
Ventas[Fecha] < MIN(Calendario[Date])
)
)
Probemos el código seleccionando una fecha en el segmentador que incluya solo un par de ventas:
', 'es') (Line: 118)
Drupal\filter\Element\ProcessedText::preRenderText(Array)
call_user_func_array(Array, Array) (Line: 101)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88)
__TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 46)
__TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 43)
__TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110)
__TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, ) (Line: 242)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
- Deprecated function: Creation of dynamic property Drupal\mysql\Driver\Database\mysql\Select::$alterTags is deprecated in Drupal\Core\Database\Query\Select->addTag() (line 149 of core/lib/Drupal/Core/Database/Query/Select.php).
Drupal\Core\Database\Query\Select->addTag('file_load_multiple') (Line: 696)
Drupal\Core\Entity\Sql\SqlContentEntityStorage->buildQuery(Array) (Line: 422)
Drupal\Core\Entity\Sql\SqlContentEntityStorage->getFromStorage(Array) (Line: 393)
Drupal\Core\Entity\Sql\SqlContentEntityStorage->doLoadMultiple(Array) (Line: 346)
Drupal\Core\Entity\EntityStorageBase->loadMultiple(Array) (Line: 641)
Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63)
Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', '889838af-b5e8-477b-9185-7f190ec4e0c2') (Line: 95)
Drupal\editor\Plugin\Filter\EditorFileReference->process('En este escenario deseamos evaluar una métrica (por ejemplo, la suma de ventas) para el total de fechas previas a una dada. Partimos de una tabla de ventas ("<em>Ventas</em>") en la que se incluye una fecha ("<em>Fecha</em>") y un precio de venta ("<em>Precio final</em>"):
Adicionalmente tenemos una tabla conteniendo un calendario que, en este escenario, no está enlazado con la tabla de ventas para evitar un filtrado automático, y una visualización tipo "segmentación" en la que seleccionamos un período de interés a partir de las fechas del calendario:
Tenemos ya creada una medida que totaliza las ventas:
Ventas = SUM(Ventas[Precio final])
Como se ha comentado, el objetivo es sumar las ventas previas al período que seleccionemos en la segmentación (es decir, solo nos interesa la fecha más antigua del período seleccionado en la segmentación). En pseudo-código sería:
Recalcula la medida "Ventas"
Para las fechas anteriores a la fecha mínima de la segmentación
Como la segmentación está filtrando el calendario (pues esta visualización se ha generado a partir de él), lo anterior sería equivalente a:
Recalcula la medida "Ventas"
Para las fechas anteriores a la fecha mínima del calendario
Este esquema encaja con la estructura de la función <a href="/dax/function/calculate">CALCULATE</a>, añadiendo como filtro el contexto dado por la segunda condición:
CALCULATE(
Medida de Ventas;
Tabla de ventas tal que Ventas[Fecha] < Fecha mínima del calendario
)
Para concretar el filtrado vamos a recurrir a la función <a href="/dax/function/filter">FILTER</a>, que acepta como primer argumento una tabla y como segundo argumento un criterio de filtrado. En este caso la tabla a filtrar es la tabla de ventas y el criterio, que la fecha de venta sea menor que la menor fecha del calendario. El código quedaría de la siguiente forma:
Ventas previas = CALCULATE(
[Ventas];
FILTER(
Ventas;
Ventas[Fecha] < MIN(Calendario[Date])
)
)
Probemos el código seleccionando una fecha en el segmentador que incluya solo un par de ventas:
', 'es') (Line: 118)
Drupal\filter\Element\ProcessedText::preRenderText(Array)
call_user_func_array(Array, Array) (Line: 101)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88)
__TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 46)
__TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 43)
__TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110)
__TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, ) (Line: 242)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
- Deprecated function: Creation of dynamic property Drupal\mysql\Driver\Database\mysql\Select::$alterMetaData is deprecated in Drupal\Core\Database\Query\Select->addMetaData() (line 178 of core/lib/Drupal/Core/Database/Query/Select.php).
Drupal\Core\Database\Query\Select->addMetaData('entity_type', 'file') (Line: 115)
Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80)
Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640)
Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63)
Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', '889838af-b5e8-477b-9185-7f190ec4e0c2') (Line: 124)
Drupal\editor\Plugin\Filter\EditorFileReference->process('En este escenario deseamos evaluar una métrica (por ejemplo, la suma de ventas) para el total de fechas previas a una dada. Partimos de una tabla de ventas ("<em>Ventas</em>") en la que se incluye una fecha ("<em>Fecha</em>") y un precio de venta ("<em>Precio final</em>"):
Adicionalmente tenemos una tabla conteniendo un calendario que, en este escenario, no está enlazado con la tabla de ventas para evitar un filtrado automático, y una visualización tipo "segmentación" en la que seleccionamos un período de interés a partir de las fechas del calendario:
Tenemos ya creada una medida que totaliza las ventas:
Ventas = SUM(Ventas[Precio final])
Como se ha comentado, el objetivo es sumar las ventas previas al período que seleccionemos en la segmentación (es decir, solo nos interesa la fecha más antigua del período seleccionado en la segmentación). En pseudo-código sería:
Recalcula la medida "Ventas"
Para las fechas anteriores a la fecha mínima de la segmentación
Como la segmentación está filtrando el calendario (pues esta visualización se ha generado a partir de él), lo anterior sería equivalente a:
Recalcula la medida "Ventas"
Para las fechas anteriores a la fecha mínima del calendario
Este esquema encaja con la estructura de la función <a href="/dax/function/calculate">CALCULATE</a>, añadiendo como filtro el contexto dado por la segunda condición:
CALCULATE(
Medida de Ventas;
Tabla de ventas tal que Ventas[Fecha] < Fecha mínima del calendario
)
Para concretar el filtrado vamos a recurrir a la función <a href="/dax/function/filter">FILTER</a>, que acepta como primer argumento una tabla y como segundo argumento un criterio de filtrado. En este caso la tabla a filtrar es la tabla de ventas y el criterio, que la fecha de venta sea menor que la menor fecha del calendario. El código quedaría de la siguiente forma:
Ventas previas = CALCULATE(
[Ventas];
FILTER(
Ventas;
Ventas[Fecha] < MIN(Calendario[Date])
)
)
Probemos el código seleccionando una fecha en el segmentador que incluya solo un par de ventas:
', 'es') (Line: 118)
Drupal\filter\Element\ProcessedText::preRenderText(Array)
call_user_func_array(Array, Array) (Line: 101)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88)
__TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 46)
__TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 43)
__TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110)
__TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, ) (Line: 242)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
- Deprecated function: Creation of dynamic property Drupal\mysql\Driver\Database\mysql\Select::$alterTags is deprecated in Drupal\Core\Database\Query\Select->addTag() (line 149 of core/lib/Drupal/Core/Database/Query/Select.php).
Drupal\Core\Database\Query\Select->addTag('entity_query') (Line: 147)
Drupal\Core\Entity\Query\Sql\Query->prepare() (Line: 80)
Drupal\Core\Entity\Query\Sql\Query->execute() (Line: 640)
Drupal\Core\Entity\EntityStorageBase->loadByProperties(Array) (Line: 63)
Drupal\Core\Entity\EntityRepository->loadEntityByUuid('file', '889838af-b5e8-477b-9185-7f190ec4e0c2') (Line: 124)
Drupal\editor\Plugin\Filter\EditorFileReference->process('En este escenario deseamos evaluar una métrica (por ejemplo, la suma de ventas) para el total de fechas previas a una dada. Partimos de una tabla de ventas ("<em>Ventas</em>") en la que se incluye una fecha ("<em>Fecha</em>") y un precio de venta ("<em>Precio final</em>"):
Adicionalmente tenemos una tabla conteniendo un calendario que, en este escenario, no está enlazado con la tabla de ventas para evitar un filtrado automático, y una visualización tipo "segmentación" en la que seleccionamos un período de interés a partir de las fechas del calendario:
Tenemos ya creada una medida que totaliza las ventas:
Ventas = SUM(Ventas[Precio final])
Como se ha comentado, el objetivo es sumar las ventas previas al período que seleccionemos en la segmentación (es decir, solo nos interesa la fecha más antigua del período seleccionado en la segmentación). En pseudo-código sería:
Recalcula la medida "Ventas"
Para las fechas anteriores a la fecha mínima de la segmentación
Como la segmentación está filtrando el calendario (pues esta visualización se ha generado a partir de él), lo anterior sería equivalente a:
Recalcula la medida "Ventas"
Para las fechas anteriores a la fecha mínima del calendario
Este esquema encaja con la estructura de la función <a href="/dax/function/calculate">CALCULATE</a>, añadiendo como filtro el contexto dado por la segunda condición:
CALCULATE(
Medida de Ventas;
Tabla de ventas tal que Ventas[Fecha] < Fecha mínima del calendario
)
Para concretar el filtrado vamos a recurrir a la función <a href="/dax/function/filter">FILTER</a>, que acepta como primer argumento una tabla y como segundo argumento un criterio de filtrado. En este caso la tabla a filtrar es la tabla de ventas y el criterio, que la fecha de venta sea menor que la menor fecha del calendario. El código quedaría de la siguiente forma:
Ventas previas = CALCULATE(
[Ventas];
FILTER(
Ventas;
Ventas[Fecha] < MIN(Calendario[Date])
)
)
Probemos el código seleccionando una fecha en el segmentador que incluya solo un par de ventas:
', 'es') (Line: 118)
Drupal\filter\Element\ProcessedText::preRenderText(Array)
call_user_func_array(Array, Array) (Line: 101)
Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 788)
Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 374)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88)
__TwigTemplate_a7d6005c89ae729617b9a0c2bccb1776->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 46)
__TwigTemplate_804f7948456cfe20e11a34c43439c7c2->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array, Array) (Line: 43)
__TwigTemplate_bd990293b89f3b78c69fe0ee2f7828b5->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/field/field--text-with-summary.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_94047fbdba6937b76a4479dfa1763452->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/node.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 74)
__TwigTemplate_43dffa6ad507293d1ceeb24e05ce942c->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/custom/yg_aesthetic/templates/views-view-unformatted.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view_unformatted', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array) (Line: 479)
Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 110)
__TwigTemplate_349d2f5aada73507d566397721f27ea4->doDisplay(Array, Array) (Line: 405)
Twig\Template->displayWithErrorHandling(Array, Array) (Line: 378)
Twig\Template->display(Array) (Line: 390)
Twig\Template->render(Array) (Line: 55)
twig_render_template('themes/contrib/classy/templates/views/views-view.html.twig', Array) (Line: 384)
Drupal\Core\Theme\ThemeManager->render('views_view', Array) (Line: 433)
Drupal\Core\Render\Renderer->doRender(Array) (Line: 446)
Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 204)
Drupal\Core\Render\Renderer->render(Array, ) (Line: 242)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 235)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
- Deprecated function: Return type of Drupal\google_analytics\Component\Render\GoogleAnalyticsJavaScriptSnippet::jsonSerialize() should either be compatible with JsonSerializable::jsonSerialize(): mixed, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in include() (line 10 of modules/contrib/google_analytics/src/Component/Render/GoogleAnalyticsJavaScriptSnippet.php).
include('/var/www/vhosts/interactivechaos.ovh/httpdocs/modules/contrib/google_analytics/src/Component/Render/GoogleAnalyticsJavaScriptSnippet.php') (Line: 578)
Composer\Autoload\ClassLoader::Composer\Autoload\{closure}('/var/www/vhosts/interactivechaos.ovh/httpdocs/modules/contrib/google_analytics/src/Component/Render/GoogleAnalyticsJavaScriptSnippet.php') (Line: 432)
Composer\Autoload\ClassLoader->loadClass('Drupal\google_analytics\Component\Render\GoogleAnalyticsJavaScriptSnippet') (Line: 372)
google_analytics_page_attachments(Array) (Line: 313)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}(Object, 'google_analytics') (Line: 405)
Drupal\Core\Extension\ModuleHandler->invokeAllWith('page_attachments', Object) (Line: 310)
Drupal\Core\Render\MainContent\HtmlRenderer->invokePageAttachmentHooks(Array) (Line: 288)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
- Deprecated function: Use of "static" in callables is deprecated in Drupal\user\Entity\Role::postLoad() (line 172 of core/modules/user/src/Entity/Role.php).
Drupal\user\Entity\Role::postLoad(Object, Array) (Line: 423)
Drupal\Core\Entity\EntityStorageBase->postLoad(Array) (Line: 353)
Drupal\Core\Entity\EntityStorageBase->loadMultiple() (Line: 126)
eu_cookie_compliance_page_attachments(Array) (Line: 313)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}(Object, 'eu_cookie_compliance') (Line: 405)
Drupal\Core\Extension\ModuleHandler->invokeAllWith('page_attachments', Object) (Line: 310)
Drupal\Core\Render\MainContent\HtmlRenderer->invokePageAttachmentHooks(Array) (Line: 288)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 132)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
call_user_func(Array, Object, 'kernel.view', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 174)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 191)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 128)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 82)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 713)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)