Como usar Map, Filter y Reduce en JavaScript

Fuente: https://code.tutsplus.com/es/tutorials/how-to-use-map-filter-reduce-in-javascript–cms-26209

La programación funcional ha estado creando gran revuelo en el mundo del desarrollo estos días. Y por una buena razón: las técnicas funcionales pueden ayudarte a escribir código más declarativo que es fácil de entender en una ojeada, refactorizar y testear.

Uno de los pilares de la programación funcional es su especial uso de listas y operaciones de listas. Y esas cosas son exactamente lo que suenan: arrays de cosas y lo que haces con ellas. Pero el enfoque funcional las trata un poco diferente de lo que podrías esperar.

Este artículo le da una mirada de cerda a los llamados tres grandes operadores de las listas: mapfilter y reduce Comprender estas tres funciones constituye un paso importante para poder escribir código funcional limpio y te abre las puertas a las potentes técnicas de la programación funcional y reactiva.

Esto también significa que nunca volverás a escribir un for de nuevo.

¿Quieres saber más? Vamos a ello

Un map de lista a lista

A menudo, nos encontramos en la necesidad de tomar un array y modificar cada elemento de la misma manera. Los ejemplos tipicos son elevar al cuadrado cada elemento de un array de números, recibir el nombre d euna lista de usuarios o correr una expresión regular a un array de strings.

map es un método construido para hacer exactamente eso. Está definido en Array.prototype, entonces puedes llamarlo en cualquier array y acepta un callback como primer argumento.

Cuando llamas un map en un array, este ejecuta el callback en cada elemento dentro de él, retornando un nuevo array con los valores que el callback retorna.

Bajo el capó, map pasa tres argumentos a tu callback:

  1. El item actual en el array
  2. El indice en el array del elemento actual
  3. El array entero al que estas mapeando.

Veamos algo de código

map en la práctica

Supongamos que tenemos una app que mantiene un array de tus tareas del día. Cada tarea es un objeto de nombre task, cada uno con las propiedades name y duration.

// Durations are in minutes

var tasks = [

  {

    'name'     : 'Write for Envato Tuts+',

    'duration' : 120

  },

  {

    'name'     : 'Work out',

    'duration' : 60

  },

  {

    'name'     : 'Procrastinate on Duolingo',

    'duration' : 240

  }

];

Digamos que queremos crear un nuevo array con solo el nombre de cada tarea, entonces podemos darle una mirada a todo lo que hemos hecho en el día. Usando un ciclo for, escribiríamos algo como esto:

var task_names = [];

for (var i = 0, max = tasks.length; i < max; i += 1) {

    task_names.push(tasks[i].name);

}

JavaScript también ofrece un ciclo forEach Este funciona como un for, pero maneja por nosotros todo el desorden de revisar en cada iteracion el indice contra la longitud del array.

var task_names = [];

tasks.forEach(function (task) {

    task_names.push(task.name);
    
});

Usando map podemos escribir

var task_names = tasks.map(function (task, index, array) {

    return task.name; 

});

He incluido los parámetros index y array para recordarle que estan ahi si los necesita. Desde que no los usamos aqui, podrias omitirlos y el código seguiría funcionando bien.

Hay algunas diferencias importantes entre los dos enfoques.

  1. Usando map, no tienes que preocuparte el estado del ciclo for por ti mismo.
  2. Puedes operar en el elemento directamente, en lugar de obtenerlo con su indice en el array.
  3. No necesitas crear un nuevo array y hacer push en él. map retorna el producto final de una vez, por lo que podemos simplemente asignar el valor de retorno a una nueva variable.
  4. Recuerda incluir un return en tu callback. Si no lo haces, obtendrás un nuevo array lleno de undefined.

Resulta que todas las funciones que veremos hoy comparten las mismas características.

El hecho de que no tengamos que manejar manualmente el estado del ciclo hace nuestro código simple y más mantenible. El hecho de que podamos operar directamente en el elemento en lugar de usar su indice en el array, hace las cosas más legibles.

El uso de un forEach soluciona ambos problemas por nosotros Pero map sigue teniendo al menos dos ventajas distinguibles:

  1. forEach retorna undefined, por lo que no se puede encadenar con otros métodos de un array. map retorna un array, por lo que puedes encadenarlo con otros métodos de los arrays.
  2. map retorna un array con el producto final, en lugar de requerirnos ir transformando un array dentro del ciclo.

Mantener el numero de lugares donde modificas un estado al minimo es un importante principio en la programación funcional. Se hace para tener un código más seguro y más inteligible.

Ahora es buen momento para apuntar a que si estas en Node, pruebas estos ejemplos en la consola de Firefox o usas Babel o Traceur, puedes hacer este código más conciso con funciones de flecha.

var task_names = tasks.map((task) => task.name );

Arrow function permiten omitir la palabra return cuando el código es de una sola línea.

No se puede ser más legible que eso.

Trucos

El callback que pasas al map debe tener una setencia return específica o el map devolverá un array lleno de undefined. No es dificil recordar incluir un valor return, pero no es dificil olvidarlo.

Si se olvida, el map no se quejará. En lugar de eso, tranquilamente devolverá un array lleno de nada. Los errores silenciosos como ese pueden ser sorprendentemente difíciles de depurar.

Afortunadamente, este es el únicasorpresa con map. Pero es una falla bastante común que estoy obligado a enfatizar: ¡Asegúrese siempre de que su devolución de llamada contenga la declaración return!

Implementación

Implementaciones de lectura es una parte importante de la comprensión. Así que, vamos a escribir nuestro propio map ligero para entender mejor lo que está pasando bajo el capó. Si desea ver una implementación de calidad de producción, consulte el Polyfill de Mozilla en MDN.

var map = function (array, callback) {

    var new_array = [];

    array.forEach(function (element, index, array) {
       new_array.push(callback(element)); 
    });

    return new_array;

};

var task_names = map(tasks, function (task) {

    return task.name;

});

Este código acepta un array y la función de devolución de llamada como argumentos. A continuación, crea una nueva array; Ejecuta la devolución de llamada en cada elemento de la matriz en la que pasamos; Empuja los resultados en el nuevo array; Y devuelve el nuevo array. Si ejecuta esto en su consola, obtendrá el mismo resultado que antes. ¡Sólo asegúrese de inicializar las tasks antes de probarlo!

Mientras estamos utilizando un bucle for detras de escena, envolviéndolo en una función oculta los detalles y nos permite trabajar con la abstracción en su lugar.

Eso hace que nuestro código sea más declarativo—dice qué hacer, no cómo hacerlo. Apreciará cuánto más legible, fácil de mantener, y, erm,  depurable esto puede hacer su código.Advertisement

Filtrar el ruido

El siguiente de nuestras operaciones del arsenal es filter. Hace exactamente lo que suena: toma una array, y filtra los elementos no deseados.

Al igual que mapfilter se define en Array.prototype. Está disponible en cualquier array y le pasa una devolución de llamada como su primer argumento. Filter ejecuta esa devolución de llamada en cada elemento de la array y devuelve un nuevo array que contiene sólo los elementos para los que la devolución de llamada devuelve true.

También como mapfilter pasa su devolución de llamada tres argumentos:

  1. El elemento actual
  2. El índice actual
  3. La array a la que llamó a filter

filter en la práctica

Vamos a revisar nuestro ejemplo de task. En lugar de sacar los nombres de cada tarea, digamos que quiero obtener una lista de sólo las tareas que me llevó dos horas o más para hacer.

Usando forEach, escribiríamos:

var difficult_tasks = [];

tasks.forEach(function (task) {
    if (task.duration >= 120) {
        difficult_tasks.push(task);
    }
});

Con filter:

var difficult_tasks = tasks.filter(function (task) {
    return task.duration >= 120;
});

// Using ES6
var difficult_tasks = tasks.filter((task) => task.duration >= 120 );

Aquí, he avanzado y deje de lado los argumentos array e index a nuestra devolución de llamada, ya que no los usamos.

Al igual que mapfilter nos permite:

  • Evitar la mutación de un array dentro de un forEach o el bucle for
  • Asignar su resultado directamente a una nueva variable, en lugar de empujar en un array que hemos definido en otra parte

Sorpresas

La devolución de llamada que pasas a map debe incluir una declaración de devolución si desea que funcione correctamente. Con filter, también tiene que incluir una declaración de devolución, y debe asegurarse de que devuelve un valor booleano.

Si olvida su declaración de devolución, su devolución de llamada volverá undefined, cuyo filter coaccionará de manera inútil a false. En lugar de lanzar un error, devolverá silenciosamente un array vacía.

Si vas a la otra ruta y devuelve algo que no es explícitamente true o false, entonces el filter tratará de averiguar lo que quieres decir con la aplicación de las reglas de coerción de JavaScript. Más a menudo que no, esto es un error. Y, al igual que el olvido de su declaración de devolución, será un silencio.

Asegúrese siempre de que sus devoluciones de llamada incluyan una declaración de devolución explícita. Y asegúrese siempre de que sus devoluciones de llamada en filter devuelvan true o false. Su cordura se lo agradecerá.Advertisement

Implementación

Una vez más, la mejor manera de entender un pedazo de código es … bueno, escribirlo. Vamos a hacer rodar nuestro propio filter ligero. La buena gente de Mozilla tiene un polyfill de fuerza industrial para que leas, también.

var filter = function (array, callback) {

    var filtered_array = [];

    array.forEach(function (element, index, array) {
        if (callback(element, index, array)) {
            filtered_array.push(element);    
        }
    });

    return filtered_array;

};

Reducción de Arrays

map crea una nueva array mediante la transformación de cada elemento en una array, de forma individual. filter crea una nueva matriz eliminando los elementos que no pertenecen. reduce, por otro lado, toma todos los elementos en un array, y los reduce en un solo valor.

Al igual que el map y filterreduce se define en Array.prototype y está disponible en cualquier matriz y pasa una devolución de llamada como su primer argumento. Pero también toma un segundo argumento opcional: el valor para comenzar a combinar todos los elementos en una array.

reduce pasa la devolución de llamada cuatro argumentos:

  1. El valor actual
  2. El valor anterior
  3. El índice actual
  4. La array de la que llamas a reduce

Observe que la devolución de llamada obtiene un valor anterior en cada iteración. En la primera iteración, no hay valor anterior. Esta es la razón por la que tiene la opción de pasar a reduce un valor inicial: Actúa como el «valor anterior» para la primera iteración, cuando de otro modo no sería uno.

Por último, tenga en cuenta que reduce devuelve un solo valor, no una array que contiene un único elemento. Esto es más importante de lo que podría parecer, y volveré a él en los ejemplos.

reduce en la práctica

Dado que reduce es la función que la gente encuentra más extraterrestre al principio, comenzaremos caminando paso a paso a través de algo sencillo.

Digamos que queremos encontrar la suma de una lista de números. Usando un bucle, que asi:

var numbers = [1, 2, 3, 4, 5],
    total = 0;
    
numbers.forEach(function (number) {
    total += number;
});

Si bien esto no es un mal caso de uso para forEachreduce aún tiene la ventaja de permitirnos evitar la mutación. Con reduce, escribiríamos:

var total = [1, 2, 3, 4, 5].reduce(function (previous, current) {
    return previous + current;
}, 0);

Primero, llamamos reduce en nuestra lista de númbers. Pasamos una devolución de llamada, que acepta el valor anterior y el valor actual como argumentos, y devuelve el resultado de agregarlos juntos. Puesto que pasamos 0 como segundo argumento para reduce, usaremos eso como el valor de previous en la primera iteración.

Si lo tomamos paso a paso, se ve así:

IteraciónAnteriorActualTotal
1011
2123
3336
46410
510515

Si no eres un fanático de las tablas, ejecuta este fragmento en la consola:

var total = [1, 2, 3, 4, 5].reduce(function (previous, current, index) {
    var val = previous + current;
    console.log("The previous value is " + previous + 
                "; the current value is " + current +
                ", and the current iteration is " + (index + 1));
    return val;
}, 0);

console.log("The loop is done, and the final value is " + total + ".");

Para recapitular: reduce las iteraciones sobre todos los elementos de una array, combinándolos como se especifique en la devolución de llamada. En cada iteración, su devolución de llamada tiene acceso al valor anterior, que es el valor total-hasta-ahora, o acumulado; El valor actual; El índice actual; Y el array entero, si usted los necesita.

Volvamos a nuestro ejemplo de tareas. Hemos obtenido una lista de nombres de tareas de map, y una lista filtrada de tareas que tomó mucho tiempo con … bueno, filter.

¿Y si queríamos saber la cantidad total de tiempo que pasamos trabajando hoy?

Usando un bucle forEach, escribirías:

var total_time = 0;
    
tasks.forEach(function (task) {
    // The plus sign just coerces 
    // task.duration from a String to a Number
    total_time += (+task.duration);
});

Con reduce, se convierte en:

var total_time = tasks.reduce(function (previous, current) {
    return previous + current;
}, 0);

// Using arrow functions
var total_time = tasks.reduce((previous, current) previous + current );

Fácil.

Eso es casi todo lo que hay. Casi, porque JavaScript nos proporciona un método más poco conocido, llamado reduceRight. En los ejemplos anteriores, reduce iniciado en el primer elemento de la array, iterando de izquierda a derecha:

var array_of_arrays = [[1, 2], [3, 4], [5, 6]];
var concatenated = array_of_arrays.reduce( function (previous, current) {
        return previous.concat(current);
});

console.log(concatenated); // [1, 2, 3, 4, 5, 6];

reduceRight hace lo mismo, pero en la dirección opuesta:

var array_of_arrays = [[1, 2], [3, 4], [5, 6]];
var concatenated = array_of_arrays.reduceRight( function (previous, current) {
        return previous.concat(current);
});

console.log(concatenated); // [5, 6, 3, 4, 1, 2];

Yo uso reduce todos los días, pero nunca he necesitado reduceRight. Creo que probablemente tampoco. Pero en el caso de que alguna vez lo hagas, ahora sabes que está ahí.

Sorpresas

Las tres grandes sorpresas con reduce son:

  1. Olvidar return
  2. Olvidar un valor inicial
  3. Esperar una matriz cuando reduce devuelve un valor único

Afortunadamente, los dos primeros son fáciles de evitar. Decidir cuál debe ser su valor inicial depende de lo que está haciendo, pero conseguirá aprender como funciona rápidamente.

El último podría parecer un poco extraño. Si reduce sólo alguna vez devuelve un valor único, ¿por qué esperaría un array?

Hay algunas buenas razones para eso. Primero, reduce siempre devuelve un solo valor, no siempre un solo número. Si reduce una array de arrays, por ejemplo, devolverá un array único. Si está en el hábito o la reducción de arrays, sería justo esperar que un array que contiene un solo elemento no sería un caso especial.

En segundo lugar, si reduce devuelve una matriz con un solo valor, sería natural jugar agradable con map y filter, y otras funciones en los arrays que es probable que esté usando con él.

Implementación

Es hora de nuestra última mirada bajo el capó. Como de costumbre, Mozilla tiene un polyfill a prueba de balas para reducir si desea comprobarlo.

var reduce = function (array, callback, initial) {
    var accumulator = initial || 0;
    
    array.forEach(function (element) {
       accumulator = callback(accumulator, array[i]);
    });
    
    return accumulator;
};

Dos cosas a tener en cuenta, aquí:

  1. Esta vez, usé el nombre accumulator en vez de previous. Esto es lo que normalmente verá en otros lugares.
  2. Asigno al accumulator un valor inicial, si un usuario proporciona uno, y por defecto a 0, si no. Así es como el real reduce se comporta, también.

Ponerlo todo junto: Map, Filter, Reduce, y Encadenamiento

En este punto, es posible que no esté tan impresionado.

Justamente: mapfilter, y reduce, por su cuenta, no son muy interesantes.

Después de todo, su verdadero poder radica en su capacidad de encadenamiento.

Digamos que quiero hacer lo siguiente:

  1. Recoger dos días de tareas.
  2. Convertir las duraciones de las tareas en horas, en lugar de minutos.
  3. Filtrar todo lo que tomó dos horas o más.
  4. Sumar todo.
  5. Multiplique el resultado por una tarifa por hora para facturación.
  6. Produce una cantidad formateada en dólares.

En primer lugar, vamos a definir nuestras tareas para el lunes y el martes:

var monday = [
        {
            'name'     : 'Write a tutorial',
            'duration' : 180
        },
        {
            'name'     : 'Some web development',
            'duration' : 120
        }
    ];

var tuesday = [
        {
            'name'     : 'Keep writing that tutorial',
            'duration' : 240
        },
        {
            'name'     : 'Some more web development',
            'duration' : 180
        },
        {
            'name'     : 'A whole lot of nothing',
            'duration'  : 240
        }
    ];
    
var tasks = [monday, tuesday];

Y ahora, nuestra transformación para que se vea bien:

    var result = tasks.reduce(function (accumulator, current) {
                        return accumulator.concat(current);
                    }).map(function (task) {
                        return (task.duration / 60);
                    }).filter(function (duration) {
                        return duration >= 2;
                    }).map(function (duration) {
                        return duration * 25;
                    }).reduce(function (accumulator, current) {
                        return [(+accumulator) + (+current)];
                    }).map(function (dollar_amount) {
                        return '$' + dollar_amount.toFixed(2);
                    }).reduce(function (formatted_dollar_amount) {
                        return formatted_dollar_amount;
                    });

O, más concisamente:

                  // Concatenate our 2D array into a single list
var result = tasks.reduce((acc, current) => acc.concat(current))
                  // Extract the task duration, and convert minutes to hours
                  .map((task) => task.duration / 60)
                  // Filter out any task that took less than two hours
                  .filter((duration) => duration >= 2)
                  // Multiply each tasks' duration by our hourly rate
                  .map((duration) => duration * 25)
                  // Combine the sums into a single dollar amount
                  .reduce((acc, current) => [(+acc) + (+current)])
                  // Convert to a "pretty-printed" dollar amount
                  .map((amount) => '$' + amount.toFixed(2))
                  // Pull out the only element of the array we got from map
                  .reduce((formatted_amount) =>formatted_amount); 

Si has llegado tan lejos, esto debería ser bastante sencillo. Sin embargo, hay dos rarezas que explicar.

Primero, en la línea 10, tengo que escribir:

// Remainder omitted
reduce(function (accumulator, current) {
    return [(+accumulator) + (+current_];
})

Dos cosas para explicar aquí:

  1. Los signos + frente al accumulator y current coaccionan sus valores a números. Si no lo hace, el valor devuelto será la cadena bastante inútil, "12510075100".
  2. Si no envuelve esa suma entre paréntesis, reduce devolvera un solo valor, no un array. ¡Eso terminaría lanzando un TypeError, porque puede utilizar solamente el map en un array!

El segundo bit que podría ponerte incómodo es el último reduce, a saber:

// Remainder omitted
map(function (dollar_amount) {
    return '$' + dollar_amount.toFixed(2);
}).reduce(function (formatted_dollar_amount) {
    return formatted_dollar_amount;
});

Esta llamada al map devuelve un array que contiene un solo valor. Aquí, llamamos reduce para obtener ese valor.

La otra manera de hacerlo sería quitar la llamada a reduce e indexar en el array que map devuelve:

var result = tasks.reduce(function (accumulator, current) {
                    return accumulator.concat(current);
                }).map(function (task) {
                    return (task.duration / 60);
                }).filter(function (duration) {
                    return duration >= 2;
                }).map(function (duration) {
                    return duration * 25;
                }).reduce(function (accumulator, current) {
                    return [(+accumulator) + (+current)];
                }).map(function (dollar_amount) {
                    return '$' + dollar_amount.toFixed(2);
                })[0];

Eso es perfectamente correcto. Si está más cómodo usando un índice de array, siga adelante.

Pero le recomiendo que no lo haga. Una de las formas más poderosas de utilizar estas funciones es en el ámbito de la programación reactiva, en la que no podrá utilizar índices de array. Patear ese hábito ahora hará que aprender técnicas reactivas mucho más fácil mas adelante.

Finalmente, vamos a ver cómo nuestro amigo el bucle forEach lo haría:

var concatenated = monday.concat(tuesday),
    fees = [],
    formatted_sum,
    hourly_rate = 25,
    total_fee = 0;

concatenated.forEach(function (task) {
    var duration = task.duration / 60;
    
    if (duration >= 2) {
        fees.push(duration * hourly_rate);
    }
});

fees.forEach(function (fee) {
    total_fee += fee
});


var formatted_sum = '$' + total_fee.toFixed(2);

Tolerable, pero desordenado.

Conclusión y próximos pasos

En este tutorial, has aprendido cómo trabajan mapfilter y reduce; Cómo usarlos; Y aproximadamente cómo se implementan. Usted ha visto que todos ellos le permiten evitar el estado mutante, que utilizando for y forEach cada lazos requiere, y ahora debe tener una buena idea de cómo encadenar todos juntos.

Mover archivos mdf y ldf sql server

Al hacer el movimiento entre unidades de disco de los archivos, apareció un error de acceso a las unidades, eso es porque hay que asignar permisos al usuario de servicio MSSQLSERVER a los archivos en la unidad nueva.

El usuario se debe buscar como NT SERVICE\MSSQLSERVER y con ello ya se pueden asignar los permisos.

Check TestDB file permission for mdf and ldf

SAP ITS MOBILE

ivanchodelatdic. ’15

#¿Qué es SAP® ITSMOBILE?SAP_ITS_mobile.jpg800×886 100 KB
ITSMOBILE es una tecnología basada en el navegador que permite que cualquier dispositivo móvil se conecte con SAP y soporte tareas de captura de datos.

ITS MOBILE es la versión para dispositivos móviles del SAP Internet Transaction Server.

ITSMOBILE se usa de forma estándar en los módulos WM (Warehouse management) y YM (Yard Management). También es usado en el EWM (Extended Warehouse Management).
ITSMOBILE puede ser usado en cualquier módulo de SAP ECC, que requiera la captura de datos a través de desarrollos ABAP y un editor HTML.
Existen tecnologías anteriores que su uso actual es reducido debido a que no tienen las capacidades del nuevo ITSMOBILE o que ya nos son soportadas por SAP.

##Qué es Radiofrecuencia SAP®
ITSMOBILE nos da la capacidad de ejecutar transacciones de SAP directamente en equipos de radiofrecuencia (conectado con el ITSMOBILE) a través de un dispositivo de mano o montado en un montacargas que elimina la necesidad de middleware ya que los dispositivos se conectan directamente a SAP.

La solución SAP se centra en manejo de la información en tiempo real, del flujo de los materiales.

El concepto de tener las pantallas y la lógica de negocio dentro del sistema SAP hace que sea fácil de administrar. Es fácil de distribuir los nuevos procesos a cada dispositivo, y fácil de configurar.
Las pantallas pueden ser ajustadas modificando el código html y el CSS, para mejorar la presentación.
Las últimas implementaciones de SAP para reforzar las capacidades del ITSMOBILE como lo es ITSmobile Visual Editor, que permite la verdadera edición del HTML generado y de estilos CSS más la llegada de dispositivos portátiles con navegadores modernos hacen que ya sea posible dar un gran salto hacia adelante en cuando a la usabilidad y presentación de aplicaciones. Al mismo tiempo esto también posibilita la entrada en juego de otros dispositivos móviles no robustos con procesadores rápidos y grandes pantallas.

##Ventajas:
Es ABAP: las aplicaciones para los dispositivos móviles se escriben en ABAP teniendo acceso a toda la lógica del negocio que se encuentra en el ECC. También cualquier modificación o nueva implementación es fácil para el equipo de sistemas interno después de contar con una breve experiencia.

No es necesario usar ningún software intermedio no siendo necesario inversiones de dinero y tiempo en servidores intermedios, virtualización, licencias, soporte, etc.

Las aplicaciones también pueden ser accedidas desde el SAP-GUI lo que puede ser usado como contingencia si falla un dispositivo móvil o como ambiente de pruebas sin requerir el dispositivo.1 Respuesta8

  • creadodic. ’15
  • última respuestaene. ’17
  • 5respuestas
  • 9,1kvistas
  • 3usuarios
  • 17me gusta
  • 4enlaces

smotaene. ’16

 ivanchodelat:

Radiofrecuencia SAP

Buenisima la info que pones aca, podrias indicarme porque usar o desarrollar para Radiofrecuencia SAP y no para fiori, ya que SAP esta haciendo mucho exfuersos por promover el uso de fiori para ejecutar las transacciones de ECC en mobiles.1

ivanchodelatene. ’16

Hola
Esta es una pregunta muy buena.
Te contesto desde mi experiencia, y con el ánimo de abrir un debate con los miembros del foro.

SAP hizo el ITS-Mobile para soportar específicamente las transacciones estándar para terminales portátiles con lector de códigos de barras que existen en el módulo de WM y EWM.

Estas transacciones están pensadas para procesos muy específicos en el piso del centro de centro de distribución, bodega o almacén. La operación es realizada por operarios que cargan tarimas, acomodan materiales, etc y todo es apoyado en etiquetas de códigos de barras.
Por la operación y las condiciones en las que se ejecuta los dispositivos móviles son un poco especiales. Resistente a los golpes, lectores de códigos de barras incluidos, teclados físicos grandes para operar con guantes y baterías de muy larga duración.
Son conocidos como HAND-HELD, y las marcas más conocidas son: Motorola-Symbol-zebra, hand hel products, Intermec, Pzion, etc…

Estos equipos y la operación que cumplen, parece muy distinta a la que se enfoca SAP Fiori que está pensada más para equipos como teléfonos y tabletas. Ademas los demos se ven con transacciones más orientadas hacia la administración.
Experience SAP Fiori UX
h_tps://www.sapfioritrial.com

La respuesta que le doy a mis clientes.

  1. La interfaz gráfica que propone SAP FIORI, No está pensada para la operación en el piso de la planta de producción o el almacén. Fiori Es una interfaz más amigable con la que interactúas varias veces, ves reportes gráficos entre otros. En el almacén buscas un escaneo de un código de barras y ya, en algunos casos la confirmación de una cantidad de material mediante un teclado físico, sin que el operario se quite los guantes, y procurando toque la menos cantidad posible de veces la pantalla.
  2. Normalmente el nivel de actualización del servidor SAP (Support Package ), que se requiere para implementar Fiori
    h_tp://scn.sap.com/community/mobile/blog/2013/10/02/sap-fiori-ll09--check-the-latest-support-package-level
    Lo poseen pocos clientes y lo que cuesta llevar el servidor a ese nivel desalienta a muchos.
  3. Aunque pareciera que SAP Fiori, Fuera el remplazo de SAP ITS-MOBILE. no es así ya que continuamente hay nuevas actualizaciones en el servicio de ITS-Mobile como lo es ITSmobile Visual Editor que requiere Support Package (7.40 as of SAPKB74003)
  4. Aunque hay varias soluciones como Fiori, XAMARAN, GuiXT… SAP ITS-Mobile está disponible desde SAP ECC 6.0, sin pagar nada más en licencias de paquetes, no hay invertir tiempo en aprender nuevos lenguajes y plataformas de desarrollo, se desarrolla sobre ABAP, no hay ningún tipo de servidor intermedio y en las terminales se conecta a sap por medio del navegador del equipo móvil.

Otras ventajas: estas transacciones desarrolladas para ITS-mobile pueden ser accedidas desde el SAP Gui o desde dispositivos móviles como teléfonos o Tablets… Pudieran ser utilizados en algún momento.
Es posible desarrollar aplicaciones para cualquier modulo del ECC, si encuentras la utilidad de captura de datos en campo, es posible desarrollar aplicaciones para. MM, PP PM, QM etc…

Integramos SAP ITSMOBILE, etiquetas de código de barras, terminales con lector de códigos de barras y desarrollo ABAP, Se crean aplicaciones web que pueden correr en terminales portatiles de códigos de barras.

Ejecutar estas aplicaciones en equipos portátiles permite que los procesos se contabilicen directamente en la ubicación de la actividad física en la que se generan los datos.

Como conclusión personal:
Creo que para las operaciones donde se requiere el manejo especial de la operación la mejor opción seguirá siendo el ITS-mobile y el sap fiori complementara las capacidades de la operación de almacenes y plantas de producción.
Ademas es bueno que SAP permita muchas opciones para que los clientes evalúen la solución que mas les conviene.

Iván Castillo

Ejemplo práctico

ITS MOBILE

ITS(Internet Transaction Server ) mobile is a SAP technology to connect mobile devices to a SAP system in order to run applications based on the widely used Dynpro programming model.

  
SAP ITS mobile used in:

  1. SAP ECC (Warehouse management, IM management (custom) and Yard Management, Task and Logistics Executions, etc. inbuilt standard SAP Tcodes).
  2. SAP EWM (Extended Warehouse Management).
  3. SAP AII (Auto ID – RFID).
  4. Non-SAP application that supports browser based devices.
  5. It can also be used for applications that built to support web browser signature capture, approval, mobile printer, GPS device, camera, etc. as long as browser supports.

ITS is ABAP applications on mobile devices that has following advantages:

  1. The entire application can be developed using ABAP workbench.
  2. SAP GUI can be used for Windows to perform ABAP debugging and system landscape is not complex.
  3. The templates and generated HTML can be custom as per business requirement.
  4. HTML or JavaScript can be used as per device types in application.
  5. ITS mobile supports data input via 1D and 2D bar code scanning.

Different types of browsers:

  1. Pocket Browser
  2. Wavelink Industrial browser
  3. Internet Explorer

ITS mobile is browser based technology and thereby be used in any mobile device and take advantages of mobile application like bar code scanner, RFID reader and voice controlled application.

  This blog only provides the details on creating ICF Services. It is assumed that a Dynpro module pool report is already present. Please refer to the below link for creation of the ICF Services.

Steps:

There are three main steps for creating an application

a) Generating an Internet Service and Templates.

b) Create an ICF service.

c) Test ICF service.

Generating an Internet Service and Templates.

In SE80 –

Select the package and create the Internet service, please check below screen shot.

Enter the service name and transaction code of test module pool program

Click on save and assign Package/Request details.

Enter Short text and verify Transaction code in the parameter tab. Then press Save.

Select all the screens in module pool program for which you want to create a template, and choose Create Template from context menu

Provide the following details

Internet Service:      That we have created earlier

Theme:                   99(Default ITS theme)

Generating Style:      Mobile Devices (No HTML Tables)

Assign package(Test Program Package)

Select the internet service created and in context menu, select Publish->Service File.

After receiving success message, Publish by selecting Publish->Complete Service.

Once published, we can see the success message saying ‘Object published successfully. Site: INTERNAL’.

This completes the generation of the service and the templates. So that you can call your service using the browser. Now we need to create an ICF service that links previously created internet service with an HTTP access path.

Create an ICF path

Go to SICF transaction; execute the report to get into the second screen.

Navigate to the path default_host/sap/bc/gui/sap/its and right click and select

‘New sub-element’.

Give the same Internet service name as given in SE80.

Provide the description 1.

Change the GUI Link status to YES  and click the GUI configurations 

In the GUI configuration tab give the following parameters:

Mandatory service Parameters

~ITSMOBILE:            The ~ITSMOBILE parameter is mandatory and must be set to 1 for all mobile services. The parameter specifies that the particular service is for mobile devices and adjusts the ITS environment accordingly.

~TRANSACTION: The ~TRANSACTION parameter defines the transaction to be started in the SAP system and thus determines the application to be run in the Web Application Server. A template must be available in the service for every screen of this application that is called.

~THEME: The ~THEME parameter defines the template set that is to be used to display the transaction. You determine which theme must be specified when you generate the template. The generator saves the templates under the theme you specify.

And enter a CL_HTTP_EXT_ITS Handler on Handler list tab

Save the service, right click and activate it.

Test the ITS application:

In Transaction SICF, Right click on the service that is created and Test Service.

  1. 2. Right click on the Internet Service that is created & click on ‘Start Service’.

It will open a webpage and will display the application as seen in a handheld device.

Enter a user ID and Password and press ‘OK’ button. It opens the web browsers shows below.

Enter a valid Sales Document number and press ‘Enter’ button.

Next screen display Sales Document Details 

If above ITS Application is execute in ABAP Editor.

  1. Input Screen

2 . Next screen (Sales Docume)

Standard ITS programs:

AIN_MOBILE
ITSMOBILE
ITSMOBILE00
ITSMOBILE01
ITSMOBILE03

16 Servicios gratis para compartir archivos

Comparativa de servicios para enviar archivos grandes

NOMBRE DEL SERVICIOTAMAÑO MÁXIMO GRATISDÍAS DISPONIBLELÍMITE DE DESCARGASTIPO DE CIFRADOREQUIERE REGISTRO
TERASHARESin límiteSin límiteSin límiteRC4Requiere una aplicación
WETRANSFER2 GB7 díasSin límiteAES-256Requiere una aplicación
SENDTHISFILESin límite3 díasSin límiteAES-256
FIREFOX SEND1 GB24 horas1AES-128No
YDRAY5 GB7 díasSin límiteNo
SMASHSin límite14 díasSin límiteSin especificarNo
MAILBIGFILE2 GB10 días20 vecesSin especificarNo
FILEMAIL50 GB7 díasSin límiteSin especificarNo
DROPSEND4 GB7 días1AES-256No
TRANSFERNOW4 GB7 díasSin límiteSin especificarNo
NOFILE.IO10 GB7 díasNo especificadoAES-128No
FASTEST FISHSin límiteHasta que desconectas el navegadorSin límiteSin especificarNo
INSTANT.IOSin límiteHasta que desconectas el navegadorSin límiteSin especificarNo
VOLAFILE20 GB2 díasSin límiteSin especificarNo
GOOGLE DRIVE15 GBSin límiteSin límiteAES-256