MQL5Book/Scripts/p5/ObjectCopy.mq5

104 lines
3.3 KiB
MQL5
Raw Permalink Normal View History

2025-05-30 16:09:41 +02:00
//+------------------------------------------------------------------+
//| ObjectCopy.mq5 |
//| Copyright 2021, MetaQuotes Ltd. |
//| https://www.mql5.com |
//| |
//| The script creates a copy for every selected object. |
//+------------------------------------------------------------------+
#include "..\..\Include\ObjectMonitor.mqh"
#define PUSH(A,V) (A[ArrayResize(A, ArraySize(A) + 1) - 1] = V)
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
int flags[2048];
// fill in the array with values of possible properties
// some invalid values will be dropped on reading from object
for(int i = 0; i < ArraySize(flags); ++i)
{
flags[i] = i;
}
// collect names of selected objects in the following array
string selected[];
const int n = ObjectsTotal(0);
for(int i = 0; i < n; ++i)
{
const string name = ObjectName(0, i);
if(ObjectGetInteger(0, name, OBJPROP_SELECTED))
{
PUSH(selected, name);
}
}
// loop through objects to copy
for(int i = 0; i < ArraySize(selected); ++i)
{
const string name = selected[i];
// backup all properties of current object
ObjectMonitor object(name, flags);
object.print();
object.backup();
const string copy = GetFreeName(name);
if(StringLen(copy) > 0)
{
Print("Copy name: ", copy);
ObjectCreate(0, copy,
(ENUM_OBJECT)ObjectGetInteger(0, name, OBJPROP_TYPE),
ObjectFind(0, name), 0, 0);
object.name(copy);
object.restore();
}
else
{
Print("Can't create copy name for: ", name);
}
}
}
//+------------------------------------------------------------------+
//| Generate a name of copy of given object, like "Original/Copy №x" |
//+------------------------------------------------------------------+
string GetFreeName(const string name)
{
const string suffix = "/Copy №";
const int pos = StringFind(name, suffix);
string prefix;
int n;
if(pos <= 0)
{
const string candidate = name + suffix + "1";
// check if a name with "/Copy №1" suffix is vacant, and return it if so
if(ObjectFind(0, candidate) < 0)
{
return candidate;
}
prefix = name;
n = 0;
}
else
{
prefix = StringSubstr(name, 0, pos);
n = (int)StringToInteger(StringSubstr(name, pos + StringLen(suffix)));
}
Print("Found: ", prefix, " ", n);
for(int i = n + 1; i < 1000; ++i) // try to create no more than 1000 copies
{
const string candidate = prefix + suffix + (string)i;
// check if an object with the name ending with "Copy №i" exists already
if(ObjectFind(0, candidate) < 0)
{
return candidate;
}
}
return NULL;
}
//+------------------------------------------------------------------+